Skip to content

Commit 5d6ab3d

Browse files
committed
complete-not-identify
1 parent 0678501 commit 5d6ab3d

File tree

9 files changed

+513
-75
lines changed

9 files changed

+513
-75
lines changed

toolchain/check/handle_require.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ static auto TypeStructureReferencesSelf(
154154

155155
struct ValidateRequireResult {
156156
SemIR::FacetType facet_type;
157+
SemIR::TypeId facet_type_type_id;
157158
const SemIR::IdentifiedFacetType* identified;
158159
};
159160

@@ -164,12 +165,14 @@ static auto ValidateRequire(Context& context, SemIR::LocId loc_id,
164165
SemIR::InstId constraint_inst_id,
165166
SemIR::InstId scope_inst_id)
166167
-> std::optional<ValidateRequireResult> {
167-
auto constraint_constant_value_inst_id =
168-
context.constant_values().GetConstantInstId(constraint_inst_id);
169-
auto constraint_facet_type = context.insts().TryGetAs<SemIR::FacetType>(
170-
constraint_constant_value_inst_id);
168+
auto constraint_constant_value_id =
169+
context.constant_values().Get(constraint_inst_id);
170+
auto constraint_type_id =
171+
SemIR::TypeId::ForTypeConstant(constraint_constant_value_id);
172+
auto constraint_facet_type =
173+
context.types().TryGetAs<SemIR::FacetType>(constraint_type_id);
171174
if (!constraint_facet_type) {
172-
if (constraint_constant_value_inst_id != SemIR::ErrorInst::InstId) {
175+
if (constraint_constant_value_id != SemIR::ErrorInst::ConstantId) {
173176
CARBON_DIAGNOSTIC(
174177
RequireImplsMissingFacetType, Error,
175178
"`require` declaration constrained by a non-facet type; "
@@ -218,6 +221,7 @@ static auto ValidateRequire(Context& context, SemIR::LocId loc_id,
218221
}
219222

220223
return ValidateRequireResult{.facet_type = *constraint_facet_type,
224+
.facet_type_type_id = constraint_type_id,
221225
.identified = &identified};
222226
}
223227

@@ -244,7 +248,7 @@ auto HandleParseNode(Context& context, Parse::RequireDeclId node_id) -> bool {
244248
return true;
245249
}
246250

247-
auto [constraint_facet_type, identified] = *validated;
251+
auto [constraint_facet_type, constraint_type_id, identified] = *validated;
248252
if (identified->required_interfaces().empty()) {
249253
// A `require T impls type` adds no actual constraints, so nothing to do.
250254
DiscardGenericDecl(context);

toolchain/check/interface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static auto GetGenericArgsWithSelfType(Context& context,
122122
arg_ids.reserve(std::max(reserve_args_size, interface_args.size() + 1));
123123

124124
// Start with the enclosing arguments from the interface.
125-
arg_ids.assign(interface_args.begin(), interface_args.end());
125+
llvm::append_range(arg_ids, interface_args);
126126

127127
// Add the `Self` argument.
128128
arg_ids.push_back(GetSelfFacet(context, interface_specific_id, generic_id,
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
2+
// Exceptions. See /LICENSE for license information.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
//
5+
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
6+
//
7+
// AUTOUPDATE
8+
// TIP: To test this file alone, run:
9+
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/generic/extend_type_completion.carbon
10+
// TIP: To dump output, run:
11+
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/generic/extend_type_completion.carbon
12+
13+
// --- class_impl_doesnt_need_complete_interface.carbon
14+
library "[[@TEST_NAME]]";
15+
16+
interface K(T:! type) {}
17+
18+
class C(N:! i32) {
19+
impl as K(array(i32, N)) {}
20+
}
21+
22+
// C does not extend K so the type of K is not completed. No error.
23+
var v: C(-1);
24+
25+
// --- fail_class_extend_impl_does_need_complete_interface.carbon
26+
library "[[@TEST_NAME]]";
27+
28+
interface K(T:! type) {}
29+
30+
class C(N:! i32) {
31+
// CHECK:STDERR: fail_class_extend_impl_does_need_complete_interface.carbon:[[@LINE+3]]:18: error: array bound of -1 is negative [ArrayBoundNegative]
32+
// CHECK:STDERR: extend impl as K(array(i32, N)) {}
33+
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
34+
extend impl as K(array(i32, N)) {}
35+
}
36+
37+
// C extends K so the type of K is completed, but is invalid.
38+
// CHECK:STDERR: fail_class_extend_impl_does_need_complete_interface.carbon:[[@LINE+4]]:8: note: in `C(-1)` used here [ResolvingSpecificHere]
39+
// CHECK:STDERR: var v: C(-1);
40+
// CHECK:STDERR: ^~~~~
41+
// CHECK:STDERR:
42+
var v: C(-1);
43+
44+
// --- interface_require_impls_doesnt_need_complete_interface.carbon
45+
library "[[@TEST_NAME]]";
46+
47+
interface K(T:! type) {}
48+
interface J(N:! i32) {
49+
require impls K(array(i32, N));
50+
}
51+
52+
// J does not extend K so the type of K is not completed. No error.
53+
var v: J(-1);
54+
55+
// --- fail_interface_extend_require_impls_does_need_complete_interface.carbon
56+
library "[[@TEST_NAME]]";
57+
58+
interface K(T:! type) {}
59+
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]
61+
// CHECK:STDERR: extend require impls K(array(i32, N));
62+
// CHECK:STDERR: ^
63+
extend require impls K(array(i32, N));
64+
}
65+
66+
// J extends K so the type of K is completed, but is invalid.
67+
//
68+
// TODO: The error location should be the type, like in the class case above. We
69+
// need a location for the type in context.bind_name_map() to use as the
70+
// location to Convert().
71+
//
72+
// 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);
74+
// CHECK:STDERR: ^~~~~~~~~~~~
75+
// CHECK:STDERR:
76+
var v: J(-1);
77+
78+
// --- constraint_require_impls_doesnt_need_complete_interface.carbon
79+
library "[[@TEST_NAME]]";
80+
81+
interface K(T:! type) {}
82+
constraint J(N:! i32) {
83+
require impls K(array(i32, N));
84+
}
85+
86+
// J does not extend K so the type of K is not completed. No error.
87+
var v: J(-1);
88+
89+
// --- fail_constraint_extend_require_impls_does_need_complete_interface.carbon
90+
library "[[@TEST_NAME]]";
91+
92+
interface K(T:! type) {}
93+
constraint J(N:! i32) {
94+
// CHECK:STDERR: fail_constraint_extend_require_impls_does_need_complete_interface.carbon:[[@LINE+3]]:37: error: array bound of -1 is negative [ArrayBoundNegative]
95+
// CHECK:STDERR: extend require impls K(array(i32, N));
96+
// CHECK:STDERR: ^
97+
extend require impls K(array(i32, N));
98+
}
99+
100+
// J extends K so the type of K is completed, but is invalid.
101+
// 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);
103+
// CHECK:STDERR: ^~~~~~~~~~~~
104+
// CHECK:STDERR:
105+
var v: J(-1);

0 commit comments

Comments
 (0)