Skip to content

Commit a18bbae

Browse files
committed
works-but-import-crash
1 parent 05af854 commit a18bbae

File tree

5 files changed

+213
-58
lines changed

5 files changed

+213
-58
lines changed

toolchain/check/eval.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,14 @@ static auto ResolveSpecificDeclForInst(EvalContext& eval_context,
867867
for (const auto& interface : info.self_impls_constraints) {
868868
ResolveSpecificDeclForSpecificId(eval_context, interface.specific_id);
869869
}
870+
for (const auto& constraint : info.extend_named_constraints) {
871+
ResolveSpecificDeclForSpecificId(eval_context,
872+
constraint.specific_id);
873+
}
874+
for (const auto& constraint : info.self_impls_named_constraints) {
875+
ResolveSpecificDeclForSpecificId(eval_context,
876+
constraint.specific_id);
877+
}
870878
break;
871879
}
872880
case CARBON_KIND(SemIR::SpecificId specific_id): {

toolchain/check/handle_require.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,9 @@ auto HandleParseNode(Context& context, Parse::RequireDeclId node_id) -> bool {
278278
// We look for a complete type after BuildGenericDecl, so that the resulting
279279
// RequireCompleteType instruction is part of the enclosing interface or named
280280
// constraint generic definition. Then requiring enclosing entity to be
281-
// complete will resolve that definition and also construct a specific for the
282-
// `constraint_inst_id`, finding any monomorphization errors that result.
281+
// complete will resolve that definition (via ResolveSpecificDefinition()) and
282+
// also construct a specific for the `constraint_inst_id`, finding any
283+
// monomorphization errors that result.
283284
if (extend) {
284285
if (!RequireCompleteType(
285286
context, constraint_type_id, SemIR::LocId(constraint_inst_id), [&] {
@@ -290,13 +291,12 @@ auto HandleParseNode(Context& context, Parse::RequireDeclId node_id) -> bool {
290291
RequireImplsIncompleteFacetType,
291292
constraint_inst_id);
292293
})) {
293-
DiscardGenericDecl(context);
294+
// DiscardGenericDecl(context);
294295
return true;
295296
}
296297
}
297298

298299
context.require_impls_stack().AppendToTop(require_impls_id);
299-
300300
return true;
301301
}
302302

toolchain/check/testdata/generic/extend_type_completion.carbon

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ library "[[@TEST_NAME]]";
5757

5858
interface K(T:! type) {}
5959
interface J(N:! i32) {
60-
// CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:37: error: array bound of -1 is negative [ArrayBoundNegative]
60+
// CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: error: array bound of -1 is negative [ArrayBoundNegative]
6161
// CHECK:STDERR: extend require impls K(array(i32, N));
62-
// CHECK:STDERR: ^
62+
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
6363
extend require impls K(array(i32, N));
6464
}
6565
interface I(N:! i32) {
66-
// CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: note: in `require` used here [ResolvingSpecificHere]
66+
// CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: note: in `J(-1)` used here [ResolvingSpecificHere]
6767
// CHECK:STDERR: extend require impls J(N);
6868
// CHECK:STDERR: ^~~~
6969
extend require impls J(N);
@@ -75,7 +75,7 @@ interface I(N:! i32) {
7575
// need a location for the type in context.bind_name_map() to use as the
7676
// location to Convert().
7777
//
78-
// CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+4]]:1: note: in `require` used here [ResolvingSpecificHere]
78+
// CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+4]]:1: note: in `I(-1)` used here [ResolvingSpecificHere]
7979
// CHECK:STDERR: var v: I(-1);
8080
// CHECK:STDERR: ^~~~~~~~~~~~
8181
// CHECK:STDERR:
@@ -97,20 +97,20 @@ library "[[@TEST_NAME]]";
9797

9898
interface K(T:! type) {}
9999
constraint J(N:! i32) {
100-
// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:37: error: array bound of -1 is negative [ArrayBoundNegative]
100+
// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: error: array bound of -1 is negative [ArrayBoundNegative]
101101
// CHECK:STDERR: extend require impls K(array(i32, N));
102-
// CHECK:STDERR: ^
102+
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
103103
extend require impls K(array(i32, N));
104104
}
105105
constraint I(N:! i32) {
106-
// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: note: in `require` used here [ResolvingSpecificHere]
106+
// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:24: note: in `{}` used here [ResolvingSpecificHere]
107107
// CHECK:STDERR: extend require impls J(N);
108108
// CHECK:STDERR: ^~~~
109109
extend require impls J(N);
110110
}
111111

112112
// I extends J extends K so the type of K is completed, but is invalid.
113-
// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+4]]:1: note: in `require` used here [ResolvingSpecificHere]
113+
// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+4]]:1: note: in `{}` used here [ResolvingSpecificHere]
114114
// CHECK:STDERR: var v: I(-1);
115115
// CHECK:STDERR: ^~~~~~~~~~~~
116116
// CHECK:STDERR:

toolchain/check/testdata/impl/incomplete.carbon

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -208,22 +208,6 @@ interface B {
208208
require impls A;
209209
}
210210

211-
// --- fail_incomplete_extend_constraint.carbon
212-
library "[[@TEST_NAME]]";
213-
214-
constraint A;
215-
216-
interface B {
217-
// CHECK:STDERR: fail_incomplete_extend_constraint.carbon:[[@LINE+7]]:24: error: facet type `A` cannot be identified in `require` declaration [RequireImplsUnidentifiedFacetType]
218-
// CHECK:STDERR: extend require impls A;
219-
// CHECK:STDERR: ^
220-
// CHECK:STDERR: fail_incomplete_extend_constraint.carbon:[[@LINE-6]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere]
221-
// CHECK:STDERR: constraint A;
222-
// CHECK:STDERR: ^~~~~~~~~~~~~
223-
// CHECK:STDERR:
224-
extend require impls A;
225-
}
226-
227211
// CHECK:STDOUT: --- fail_empty_struct.carbon
228212
// CHECK:STDOUT:
229213
// CHECK:STDOUT: constants {
@@ -876,33 +860,3 @@ interface B {
876860
// CHECK:STDOUT:
877861
// CHECK:STDOUT: constraint @A;
878862
// CHECK:STDOUT:
879-
// CHECK:STDOUT: --- fail_incomplete_extend_constraint.carbon
880-
// CHECK:STDOUT:
881-
// CHECK:STDOUT: constants {
882-
// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete]
883-
// CHECK:STDOUT: %B.type: type = facet_type <@B> [concrete]
884-
// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic]
885-
// CHECK:STDOUT: }
886-
// CHECK:STDOUT:
887-
// CHECK:STDOUT: file {
888-
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
889-
// CHECK:STDOUT: .A = %A.decl
890-
// CHECK:STDOUT: .B = %B.decl
891-
// CHECK:STDOUT: }
892-
// CHECK:STDOUT: %A.decl: type = constraint_decl @A [concrete = constants.%A.type] {} {}
893-
// CHECK:STDOUT: %B.decl: type = interface_decl @B [concrete = constants.%B.type] {} {}
894-
// CHECK:STDOUT: }
895-
// CHECK:STDOUT:
896-
// CHECK:STDOUT: interface @B {
897-
// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic = constants.%Self]
898-
// CHECK:STDOUT:
899-
// CHECK:STDOUT: !members:
900-
// CHECK:STDOUT: .Self = %Self
901-
// CHECK:STDOUT: .A = <poisoned>
902-
// CHECK:STDOUT: witness = ()
903-
// CHECK:STDOUT:
904-
// CHECK:STDOUT: !requires:
905-
// CHECK:STDOUT: }
906-
// CHECK:STDOUT:
907-
// CHECK:STDOUT: constraint @A;
908-
// CHECK:STDOUT:

toolchain/check/testdata/interface/incomplete.carbon

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,49 @@ interface I {
2828
let T:! C;
2929
}
3030

31+
// --- fail_incomplete_extend_constraint.carbon
32+
library "[[@TEST_NAME]]";
33+
34+
constraint A;
35+
36+
interface B {
37+
// CHECK:STDERR: fail_incomplete_extend_constraint.carbon:[[@LINE+7]]:24: error: facet type `A` cannot be identified in `require` declaration [RequireImplsUnidentifiedFacetType]
38+
// CHECK:STDERR: extend require impls A;
39+
// CHECK:STDERR: ^
40+
// CHECK:STDERR: fail_incomplete_extend_constraint.carbon:[[@LINE-6]]:1: note: constraint was forward declared here [NamedConstraintForwardDeclaredHere]
41+
// CHECK:STDERR: constraint A;
42+
// CHECK:STDERR: ^~~~~~~~~~~~~
43+
// CHECK:STDERR:
44+
extend require impls A;
45+
}
46+
47+
// --- fail_extend_require_enclosing.carbon
48+
library "[[@TEST_NAME]]";
49+
50+
interface A {
51+
// CHECK:STDERR: fail_extend_require_enclosing.carbon:[[@LINE+7]]:24: error: `extend require` of incomplete facet type `A` [RequireImplsIncompleteFacetType]
52+
// CHECK:STDERR: extend require impls A;
53+
// CHECK:STDERR: ^
54+
// CHECK:STDERR: fail_extend_require_enclosing.carbon:[[@LINE-4]]:1: note: interface is currently being defined [InterfaceIncompleteWithinDefinition]
55+
// CHECK:STDERR: interface A {
56+
// CHECK:STDERR: ^~~~~~~~~~~~~
57+
// CHECK:STDERR:
58+
extend require impls A;
59+
}
3160

61+
// --- fail_extend_require_enclosing_generic.carbon
62+
library "[[@TEST_NAME]]";
63+
64+
interface A(T:! type) {
65+
// CHECK:STDERR: fail_extend_require_enclosing_generic.carbon:[[@LINE+7]]:24: error: `extend require` of incomplete facet type `A({})` [RequireImplsIncompleteFacetType]
66+
// CHECK:STDERR: extend require impls A({});
67+
// CHECK:STDERR: ^~~~~
68+
// CHECK:STDERR: fail_extend_require_enclosing_generic.carbon:[[@LINE-4]]:1: note: interface is currently being defined [InterfaceIncompleteWithinDefinition]
69+
// CHECK:STDERR: interface A(T:! type) {
70+
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~
71+
// CHECK:STDERR:
72+
extend require impls A({});
73+
}
3274

3375
// CHECK:STDOUT: --- fail_incomplete_type.carbon
3476
// CHECK:STDOUT:
@@ -72,3 +114,154 @@ interface I {
72114
// CHECK:STDOUT:
73115
// CHECK:STDOUT: specific @T(constants.%Self) {}
74116
// CHECK:STDOUT:
117+
// CHECK:STDOUT: --- fail_incomplete_extend_constraint.carbon
118+
// CHECK:STDOUT:
119+
// CHECK:STDOUT: constants {
120+
// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete]
121+
// CHECK:STDOUT: %B.type: type = facet_type <@B> [concrete]
122+
// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic]
123+
// CHECK:STDOUT: }
124+
// CHECK:STDOUT:
125+
// CHECK:STDOUT: file {
126+
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
127+
// CHECK:STDOUT: .A = %A.decl
128+
// CHECK:STDOUT: .B = %B.decl
129+
// CHECK:STDOUT: }
130+
// CHECK:STDOUT: %A.decl: type = constraint_decl @A [concrete = constants.%A.type] {} {}
131+
// CHECK:STDOUT: %B.decl: type = interface_decl @B [concrete = constants.%B.type] {} {}
132+
// CHECK:STDOUT: }
133+
// CHECK:STDOUT:
134+
// CHECK:STDOUT: interface @B {
135+
// CHECK:STDOUT: %Self: %B.type = symbolic_binding Self, 0 [symbolic = constants.%Self]
136+
// CHECK:STDOUT:
137+
// CHECK:STDOUT: !members:
138+
// CHECK:STDOUT: .Self = %Self
139+
// CHECK:STDOUT: .A = <poisoned>
140+
// CHECK:STDOUT: witness = ()
141+
// CHECK:STDOUT:
142+
// CHECK:STDOUT: !requires:
143+
// CHECK:STDOUT: }
144+
// CHECK:STDOUT:
145+
// CHECK:STDOUT: constraint @A;
146+
// CHECK:STDOUT:
147+
// CHECK:STDOUT: --- fail_extend_require_enclosing.carbon
148+
// CHECK:STDOUT:
149+
// CHECK:STDOUT: constants {
150+
// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete]
151+
// CHECK:STDOUT: %Self: %A.type = symbolic_binding Self, 0 [symbolic]
152+
// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic]
153+
// CHECK:STDOUT: }
154+
// CHECK:STDOUT:
155+
// CHECK:STDOUT: file {
156+
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
157+
// CHECK:STDOUT: .A = %A.decl
158+
// CHECK:STDOUT: }
159+
// CHECK:STDOUT: %A.decl: type = interface_decl @A [concrete = constants.%A.type] {} {}
160+
// CHECK:STDOUT: }
161+
// CHECK:STDOUT:
162+
// CHECK:STDOUT: interface @A {
163+
// CHECK:STDOUT: %Self: %A.type = symbolic_binding Self, 0 [symbolic = constants.%Self]
164+
// CHECK:STDOUT: %A.require0.decl = require_decl @A.require0 [concrete] {
165+
// CHECK:STDOUT: require %Self.as_type impls <@A>
166+
// CHECK:STDOUT: } {
167+
// CHECK:STDOUT: %Self.as_type: type = facet_access_type @A.%Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)]
168+
// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type]
169+
// CHECK:STDOUT: }
170+
// CHECK:STDOUT:
171+
// CHECK:STDOUT: !members:
172+
// CHECK:STDOUT: .Self = %Self
173+
// CHECK:STDOUT: .A = <poisoned>
174+
// CHECK:STDOUT: witness = ()
175+
// CHECK:STDOUT:
176+
// CHECK:STDOUT: !requires:
177+
// CHECK:STDOUT: }
178+
// CHECK:STDOUT:
179+
// CHECK:STDOUT: generic require @A.require0(@A.%Self: %A.type) {
180+
// CHECK:STDOUT: %Self: %A.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)]
181+
// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)]
182+
// CHECK:STDOUT: }
183+
// CHECK:STDOUT:
184+
// CHECK:STDOUT: specific @A.require0(constants.%Self) {
185+
// CHECK:STDOUT: %Self => constants.%Self
186+
// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type
187+
// CHECK:STDOUT: }
188+
// CHECK:STDOUT:
189+
// CHECK:STDOUT: --- fail_extend_require_enclosing_generic.carbon
190+
// CHECK:STDOUT:
191+
// CHECK:STDOUT: constants {
192+
// CHECK:STDOUT: %type: type = facet_type <type> [concrete]
193+
// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self]
194+
// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic]
195+
// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete]
196+
// CHECK:STDOUT: %A.type.495: type = generic_interface_type @A [concrete]
197+
// CHECK:STDOUT: %A.generic: %A.type.495 = struct_value () [concrete]
198+
// CHECK:STDOUT: %A.type.c1c: type = facet_type <@A, @A(%T)> [symbolic]
199+
// CHECK:STDOUT: %Self: %A.type.c1c = symbolic_binding Self, 1 [symbolic]
200+
// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic]
201+
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
202+
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
203+
// CHECK:STDOUT: %A.type.23f: type = facet_type <@A, @A(%empty_struct_type)> [concrete]
204+
// CHECK:STDOUT: }
205+
// CHECK:STDOUT:
206+
// CHECK:STDOUT: file {
207+
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
208+
// CHECK:STDOUT: .A = %A.decl
209+
// CHECK:STDOUT: }
210+
// CHECK:STDOUT: %A.decl: %A.type.495 = interface_decl @A [concrete = constants.%A.generic] {
211+
// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete]
212+
// CHECK:STDOUT: } {
213+
// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
214+
// CHECK:STDOUT: %T.loc3_13.2: type = symbolic_binding T, 0 [symbolic = %T.loc3_13.1 (constants.%T)]
215+
// CHECK:STDOUT: }
216+
// CHECK:STDOUT: }
217+
// CHECK:STDOUT:
218+
// CHECK:STDOUT: generic interface @A(%T.loc3_13.2: type) {
219+
// CHECK:STDOUT: %T.loc3_13.1: type = symbolic_binding T, 0 [symbolic = %T.loc3_13.1 (constants.%T)]
220+
// CHECK:STDOUT:
221+
// CHECK:STDOUT: !definition:
222+
// CHECK:STDOUT: %A.type: type = facet_type <@A, @A(%T.loc3_13.1)> [symbolic = %A.type (constants.%A.type.c1c)]
223+
// CHECK:STDOUT: %Self.loc3_23.2: @A.%A.type (%A.type.c1c) = symbolic_binding Self, 1 [symbolic = %Self.loc3_23.2 (constants.%Self)]
224+
// CHECK:STDOUT:
225+
// CHECK:STDOUT: interface {
226+
// CHECK:STDOUT: %Self.loc3_23.1: @A.%A.type (%A.type.c1c) = symbolic_binding Self, 1 [symbolic = %Self.loc3_23.2 (constants.%Self)]
227+
// CHECK:STDOUT: %A.require0.decl = require_decl @A.require0 [concrete] {
228+
// CHECK:STDOUT: require %Self.as_type impls <@A, @A(constants.%empty_struct_type)>
229+
// CHECK:STDOUT: } {
230+
// CHECK:STDOUT: %Self.as_type: type = facet_access_type @A.%Self.loc3_23.1 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)]
231+
// CHECK:STDOUT: %A.ref: %A.type.495 = name_ref A, file.%A.decl [concrete = constants.%A.generic]
232+
// CHECK:STDOUT: %.loc11_27: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
233+
// CHECK:STDOUT: %.loc11_28: type = converted %.loc11_27, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
234+
// CHECK:STDOUT: %A.type.loc11_28: type = facet_type <@A, @A(constants.%empty_struct_type)> [concrete = constants.%A.type.23f]
235+
// CHECK:STDOUT: }
236+
// CHECK:STDOUT:
237+
// CHECK:STDOUT: !members:
238+
// CHECK:STDOUT: .Self = %Self.loc3_23.1
239+
// CHECK:STDOUT: .A = <poisoned>
240+
// CHECK:STDOUT: witness = ()
241+
// CHECK:STDOUT:
242+
// CHECK:STDOUT: !requires:
243+
// CHECK:STDOUT: }
244+
// CHECK:STDOUT: }
245+
// CHECK:STDOUT:
246+
// CHECK:STDOUT: generic require @A.require0(@A.%T.loc3_13.2: type, @A.%Self.loc3_23.1: @A.%A.type (%A.type.c1c)) {
247+
// CHECK:STDOUT: %T: type = symbolic_binding T, 0 [symbolic = %T (constants.%T)]
248+
// CHECK:STDOUT: %A.type.loc11_18: type = facet_type <@A, @A(%T)> [symbolic = %A.type.loc11_18 (constants.%A.type.c1c)]
249+
// CHECK:STDOUT: %Self: @A.require0.%A.type.loc11_18 (%A.type.c1c) = symbolic_binding Self, 1 [symbolic = %Self (constants.%Self)]
250+
// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)]
251+
// CHECK:STDOUT: }
252+
// CHECK:STDOUT:
253+
// CHECK:STDOUT: specific @A(constants.%T) {
254+
// CHECK:STDOUT: %T.loc3_13.1 => constants.%T
255+
// CHECK:STDOUT: }
256+
// CHECK:STDOUT:
257+
// CHECK:STDOUT: specific @A(constants.%empty_struct_type) {
258+
// CHECK:STDOUT: %T.loc3_13.1 => constants.%empty_struct_type
259+
// CHECK:STDOUT: }
260+
// CHECK:STDOUT:
261+
// CHECK:STDOUT: specific @A.require0(constants.%T, constants.%Self) {
262+
// CHECK:STDOUT: %T => constants.%T
263+
// CHECK:STDOUT: %A.type.loc11_18 => constants.%A.type.c1c
264+
// CHECK:STDOUT: %Self => constants.%Self
265+
// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type
266+
// CHECK:STDOUT: }
267+
// CHECK:STDOUT:

0 commit comments

Comments
 (0)