Skip to content

Commit a521231

Browse files
committed
test-and-fix-multi-level-specific-resolution
1 parent 48edb25 commit a521231

File tree

3 files changed

+31
-18
lines changed

3 files changed

+31
-18
lines changed

toolchain/check/testdata/generic/extend_type_completion.carbon

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,24 @@ interface J(N:! i32) {
6262
// CHECK:STDERR: ^
6363
extend require impls K(array(i32, N));
6464
}
65+
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]
67+
// CHECK:STDERR: extend require impls J(N);
68+
// CHECK:STDERR: ^~~~
69+
extend require impls J(N);
70+
}
6571

66-
// J extends K so the type of K is completed, but is invalid.
72+
// I extend J extends K so the type of K is completed, but is invalid.
6773
//
6874
// TODO: The error location should be the type, like in the class case above. We
6975
// need a location for the type in context.bind_name_map() to use as the
7076
// location to Convert().
7177
//
7278
// CHECK:STDERR: fail_interface_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+4]]:1: note: in `require` used here [ResolvingSpecificHere]
73-
// CHECK:STDERR: var v: J(-1);
79+
// CHECK:STDERR: var v: I(-1);
7480
// CHECK:STDERR: ^~~~~~~~~~~~
7581
// CHECK:STDERR:
76-
var v: J(-1);
82+
var v: I(-1);
7783

7884
// --- constraint_require_impls_doesnt_need_complete_interface.carbon
7985
library "[[@TEST_NAME]]";
@@ -96,13 +102,19 @@ constraint J(N:! i32) {
96102
// CHECK:STDERR: ^
97103
extend require impls K(array(i32, N));
98104
}
105+
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]
107+
// CHECK:STDERR: extend require impls J(N);
108+
// CHECK:STDERR: ^~~~
109+
extend require impls J(N);
110+
}
99111

100-
// J extends K so the type of K is completed, but is invalid.
112+
// I extends J extends K so the type of K is completed, but is invalid.
101113
// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+4]]:1: note: in `require` used here [ResolvingSpecificHere]
102-
// CHECK:STDERR: var v: J(-1);
114+
// CHECK:STDERR: var v: I(-1);
103115
// CHECK:STDERR: ^~~~~~~~~~~~
104116
// CHECK:STDERR:
105-
var v: J(-1);
117+
var v: I(-1);
106118

107119
// --- interface_require_impls_doesnt_need_complete_self.carbon
108120
library "[[@TEST_NAME]]";

toolchain/check/testdata/impl/import_generic.carbon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -920,9 +920,9 @@ impl forall [T:! type] D as N(T*) {}
920920
// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 1, %Self.aa1546.1 [symbolic]
921921
// CHECK:STDOUT: %ptr.3f2: type = ptr_type %ptr.4f0 [symbolic]
922922
// CHECK:STDOUT: %N.type.b8d23b.2: type = facet_type <@N, @N(%ptr.3f2)> [symbolic]
923-
// CHECK:STDOUT: %Self.aa1546.2: %N.type.b8d23b.2 = symbolic_binding Self, 1 [symbolic]
924923
// CHECK:STDOUT: %I.type.71a: type = facet_type <@I, @I(%ptr.3f2)> [symbolic]
925924
// CHECK:STDOUT: %require_complete.08c: <witness> = require_complete_type %I.type.71a [symbolic]
925+
// CHECK:STDOUT: %Self.aa1546.2: %N.type.b8d23b.2 = symbolic_binding Self, 1 [symbolic]
926926
// CHECK:STDOUT: %require_complete.a37: <witness> = require_complete_type %N.type.b8d23b.2 [symbolic]
927927
// CHECK:STDOUT: %I.impl_witness.524: <witness> = impl_witness file.%I.impl_witness_table.loc6, @C.as.I.impl.3f8(%T) [symbolic]
928928
// CHECK:STDOUT: }
@@ -1372,8 +1372,8 @@ impl forall [T:! type] D as N(T*) {}
13721372
// CHECK:STDOUT: %require_complete.a37d6c.1: <witness> = require_complete_type %N.type.b8d23b.1 [symbolic]
13731373
// CHECK:STDOUT: %J.impl_witness.b5245e.1: <witness> = impl_witness file.%J.impl_witness_table.loc29, @D.as.J.impl.3b0484.1(%T) [symbolic]
13741374
// CHECK:STDOUT: %N.type.b8d23b.2: type = facet_type <@N, @N(%ptr)> [symbolic]
1375-
// CHECK:STDOUT: %Self.aa1546.2: %N.type.b8d23b.2 = symbolic_binding Self, 1 [symbolic]
13761375
// CHECK:STDOUT: %require_complete.d4d: <witness> = require_complete_type %J.type.4fa [symbolic]
1376+
// CHECK:STDOUT: %Self.aa1546.2: %N.type.b8d23b.2 = symbolic_binding Self, 1 [symbolic]
13771377
// CHECK:STDOUT: %require_complete.a37d6c.2: <witness> = require_complete_type %N.type.b8d23b.2 [symbolic]
13781378
// CHECK:STDOUT: %J.impl_witness.b5245e.2: <witness> = impl_witness file.%J.impl_witness_table.loc39, @D.as.J.impl.3b0484.2(%T) [symbolic]
13791379
// CHECK:STDOUT: }

toolchain/check/type_completion.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
124124
MakeDiagnosticBuilderFn diagnoser)
125125
-> bool {
126126
llvm::SmallVector<SemIR::FacetTypeId> work = {facet_type.facet_type_id};
127+
llvm::SmallVector<SemIR::SpecificId> resolve;
127128
while (!work.empty()) {
128129
auto next_facet_type_id = work.pop_back_val();
129130
const auto& facet_type_info = context.facet_types().Get(next_facet_type_id);
@@ -132,7 +133,7 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
132133
SemIR::SpecificId specific_id;
133134
SemIR::RequireImplsBlockId requires_block_id;
134135
};
135-
llvm::SmallVector<SpecificForRequires> specifics;
136+
llvm::SmallVector<SpecificForRequires> specific_requires;
136137

137138
for (auto extends : facet_type_info.extend_constraints) {
138139
auto interface_id = extends.interface_id;
@@ -146,11 +147,9 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
146147
return false;
147148
}
148149
if (interface.generic_id.has_value()) {
149-
specifics.push_back(
150+
specific_requires.push_back(
150151
{extends.specific_id, interface.require_impls_block_id});
151-
}
152-
if (extends.specific_id.has_value()) {
153-
ResolveSpecificDefinition(context, loc_id, extends.specific_id);
152+
resolve.push_back(extends.specific_id);
154153
}
155154
}
156155

@@ -167,11 +166,9 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
167166
return false;
168167
}
169168
if (constraint.generic_id.has_value()) {
170-
specifics.push_back(
169+
specific_requires.push_back(
171170
{extends.specific_id, constraint.require_impls_block_id});
172-
}
173-
if (extends.specific_id.has_value()) {
174-
ResolveSpecificDefinition(context, loc_id, extends.specific_id);
171+
resolve.push_back(extends.specific_id);
175172
}
176173
}
177174

@@ -182,7 +179,7 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
182179
// declaration since `extend require` can only be applied to `Self`, so the
183180
// self-type in these `require` declarations never uses any generic
184181
// parameters.
185-
for (auto [specific_id, requires_block_id] : specifics) {
182+
for (auto [specific_id, requires_block_id] : specific_requires) {
186183
for (auto require_impls_id :
187184
context.require_impls_blocks().Get(requires_block_id)) {
188185
const auto& require = context.require_impls().Get(require_impls_id);
@@ -203,6 +200,10 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
203200
}
204201
}
205202

203+
for (auto specific_id : resolve) {
204+
ResolveSpecificDefinition(context, loc_id, specific_id);
205+
}
206+
206207
return true;
207208
}
208209

0 commit comments

Comments
 (0)