Skip to content

Commit d0f8f7c

Browse files
committed
review
1 parent a3556b2 commit d0f8f7c

File tree

3 files changed

+155
-35
lines changed

3 files changed

+155
-35
lines changed

toolchain/check/testdata/facet/access.carbon

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,27 @@ fn F(U:! I where .I1 = .Self) {
100100
(U as type) as (I where .I1 = U);
101101
}
102102

103+
// --- access_through_call_once.carbon
104+
library "[[@TEST_NAME]]";
105+
106+
// TODO: Merge this test with the one below once it works.
107+
108+
interface I {
109+
let X:! type;
110+
fn G() -> X;
111+
}
112+
113+
fn F2[U:! I](V: U) {}
114+
115+
fn F(U:! I where .X = .Self, V: U) {
116+
// The returned value of `G` type `U` which has access to the methods of `I`.
117+
U.G().G();
118+
(U as type).G().G();
119+
120+
// The returned value of type `U` can be used as a value of type `U`.
121+
F2(U.G());
122+
}
123+
103124
// --- fail_todo_access_through_call.carbon
104125
library "[[@TEST_NAME]]";
105126

@@ -114,8 +135,7 @@ fn F3[U:! I where .X = .Self](V: U) {}
114135
fn F(U:! I where .X = .Self, V: U) {
115136
// The returned value of `G` type `U` which has access to the methods of `I`.
116137
//
117-
// TODO: This works but a chained third call doesn't.
118-
U.G().G();
138+
// TODO: These should work.
119139
// - The first `.` is on a NameRef of type FacetType for `I where .X = .Self`.
120140
// - This finds `G` through the FacetType.
121141
// - The second `.` is on a Call of type FacetAccessType into `BindSymbolicName` with type FacetType for `I`.
@@ -129,8 +149,6 @@ fn F(U:! I where .X = .Self, V: U) {
129149
// CHECK:STDERR: ^~~~~~~~~~~
130150
// CHECK:STDERR:
131151
U.G().G().G();
132-
// TODO: This works but a chained third call doesn't.
133-
(U as type).G().G();
134152
// CHECK:STDERR: fail_todo_access_through_call.carbon:[[@LINE+4]]:3: error: type `.(I.X)` does not support qualified expressions [QualifiedExprUnsupported]
135153
// CHECK:STDERR: (U as type).G().G().G();
136154
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~
@@ -139,8 +157,7 @@ fn F(U:! I where .X = .Self, V: U) {
139157

140158
// The returned value of type `U` can be used as a value of type `U`.
141159
//
142-
// TODO: This works but a chaining calls to G doesn't.
143-
F2(U.G());
160+
// TODO: This should work.
144161
// CHECK:STDERR: fail_todo_access_through_call.carbon:[[@LINE+4]]:6: error: type `.(I.X)` does not support qualified expressions [QualifiedExprUnsupported]
145162
// CHECK:STDERR: F2(U.G().G().G());
146163
// CHECK:STDERR: ^~~~~~~~~~~
@@ -153,7 +170,7 @@ fn F(U:! I where .X = .Self, V: U) {
153170
// CHECK:STDERR: fail_todo_access_through_call.carbon:[[@LINE+7]]:3: error: cannot convert type `.Self` that implements `I` into type implementing `I where .(I.X) = .Self` [ConversionFailureFacetToFacet]
154171
// CHECK:STDERR: F3(U.G());
155172
// CHECK:STDERR: ^~~~~~~~~
156-
// CHECK:STDERR: fail_todo_access_through_call.carbon:[[@LINE-44]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
173+
// CHECK:STDERR: fail_todo_access_through_call.carbon:[[@LINE-40]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
157174
// CHECK:STDERR: fn F3[U:! I where .X = .Self](V: U) {}
158175
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159176
// CHECK:STDERR:
@@ -165,7 +182,7 @@ fn F(U:! I where .X = .Self, V: U) {
165182
F3(U.G().G().G());
166183
}
167184

168-
// --- fail_compound_access_through_call.carbon
185+
// --- fail_todo_compound_access_through_call.carbon
169186
library "[[@TEST_NAME]]";
170187

171188
interface I {
@@ -174,20 +191,87 @@ interface I {
174191
}
175192

176193
fn F(U:! I where .X = .Self) {
177-
// It's not possible to do compound member lookup here. You'd need
178-
// to work with `U.(I.X)` instead.
194+
// Compound member lookup through a non-type value is possible for methods
195+
// which take a `self` parameter. But it's not possible for methods without
196+
// `self`. For those you need to go directly throug the type.
179197
// See: https://github.com/carbon-language/carbon-lang/issues/6025
198+
199+
// TODO: This step should work.
200+
//
201+
// CHECK:STDERR: fail_todo_compound_access_through_call.carbon:[[@LINE+7]]:14: error: cannot implicitly convert expression of type `.Self` to `U` [ConversionFailure]
202+
// CHECK:STDERR: let u: U = U.(I.G)();
203+
// CHECK:STDERR: ^~~~~~~~~
204+
// CHECK:STDERR: fail_todo_compound_access_through_call.carbon:[[@LINE+4]]:14: note: type `.Self` does not implement interface `Core.ImplicitAs(U)` [MissingImplInMemberAccessNote]
205+
// CHECK:STDERR: let u: U = U.(I.G)();
206+
// CHECK:STDERR: ^~~~~~~~~
207+
// CHECK:STDERR:
208+
let u: U = U.(I.G)();
209+
// `u` is a non-type value. Can call methods with `self` through compound
210+
// member lookup, but can't call methods without `self`. See the
211+
// `compound_access_through_call_with_self_param.carbon` test for the former.
212+
//
213+
// CHECK:STDERR: fail_todo_compound_access_through_call.carbon:[[@LINE+4]]:6: error: value of type `<associated entity in I>` is not callable [CallToNonCallable]
214+
// CHECK:STDERR: u.(I.G());
215+
// CHECK:STDERR: ^~~~~
216+
// CHECK:STDERR:
217+
u.(I.G());
218+
219+
// This is the same as the above, since G() returns a non-type value of type
220+
// `U`.
180221
//
181-
// CHECK:STDERR: fail_compound_access_through_call.carbon:[[@LINE+7]]:3: error: cannot implicitly convert non-type value of type `.Self` into type implementing `I` [ConversionFailureNonTypeToFacet]
222+
// CHECK:STDERR: fail_todo_compound_access_through_call.carbon:[[@LINE+7]]:3: error: cannot implicitly convert non-type value of type `.Self` into type implementing `I` [ConversionFailureNonTypeToFacet]
182223
// CHECK:STDERR: U.(I.G)().(I.G)();
183224
// CHECK:STDERR: ^~~~~~~~~~~~~~~
184-
// CHECK:STDERR: fail_compound_access_through_call.carbon:[[@LINE+4]]:3: note: type `.Self` does not implement interface `Core.ImplicitAs(I)` [MissingImplInMemberAccessNote]
225+
// CHECK:STDERR: fail_todo_compound_access_through_call.carbon:[[@LINE+4]]:3: note: type `.Self` does not implement interface `Core.ImplicitAs(I)` [MissingImplInMemberAccessNote]
185226
// CHECK:STDERR: U.(I.G)().(I.G)();
186227
// CHECK:STDERR: ^~~~~~~~~~~~~~~
187228
// CHECK:STDERR:
188229
U.(I.G)().(I.G)();
189230
}
190231

232+
// --- fail_todo_compound_access_through_call_with_self_param.carbon
233+
library "[[@TEST_NAME]]";
234+
235+
interface I {
236+
let X:! type;
237+
fn G[self: Self]() -> X;
238+
}
239+
240+
fn F(U:! I where .X = .Self) {
241+
// Compound member lookup through a non-type value is possible for methods
242+
// which take a `self` parameter.
243+
244+
// TODO: This should all work.
245+
246+
// CHECK:STDERR: fail_todo_compound_access_through_call_with_self_param.carbon:[[@LINE+4]]:14: error: cannot access member of interface `I` in type `I where .(I.X) = .Self` that does not implement that interface [MissingImplInMemberAccess]
247+
// CHECK:STDERR: let u: U = U.(I.G)();
248+
// CHECK:STDERR: ^~~~~~~
249+
// CHECK:STDERR:
250+
let u: U = U.(I.G)();
251+
// `u` is a non-type value. Can call methods with `self` through compound
252+
// member lookup, but can't call methods without `self`. See the
253+
// `compound_access_through_call.carbon` test for the latter.
254+
// CHECK:STDERR: fail_todo_compound_access_through_call_with_self_param.carbon:[[@LINE+4]]:6: error: member name `G2` not found in `I` [MemberNameNotFoundInInstScope]
255+
// CHECK:STDERR: u.(I.G2());
256+
// CHECK:STDERR: ^~~~
257+
// CHECK:STDERR:
258+
u.(I.G2());
259+
260+
// This is the same as the above, since G() returns a non-type value of type
261+
// `U`.
262+
//
263+
// This works because G2 has a `self` parameter.
264+
// CHECK:STDERR: fail_todo_compound_access_through_call_with_self_param.carbon:[[@LINE+8]]:3: error: cannot access member of interface `I` in type `I where .(I.X) = .Self` that does not implement that interface [MissingImplInMemberAccess]
265+
// CHECK:STDERR: U.(I.G)().(I.G2)();
266+
// CHECK:STDERR: ^~~~~~~
267+
// CHECK:STDERR:
268+
// CHECK:STDERR: fail_todo_compound_access_through_call_with_self_param.carbon:[[@LINE+4]]:14: error: member name `G2` not found in `I` [MemberNameNotFoundInInstScope]
269+
// CHECK:STDERR: U.(I.G)().(I.G2)();
270+
// CHECK:STDERR: ^~~~
271+
// CHECK:STDERR:
272+
U.(I.G)().(I.G2)();
273+
}
274+
191275
// --- fail_non_const_associated.carbon
192276
library "[[@TEST_NAME]]";
193277

toolchain/check/testdata/facet/period_self.carbon

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ fn G(_:! I(.Self) where .I1 = ()) {}
4141
// --- fail_period_self_as_type.carbon
4242
library "[[@TEST_NAME]]";
4343

44+
// TODO: We should diagnose this use of `.Self` directly rather than later when
45+
// it is converted to `type`.
4446
interface I(T:! .Self) {
4547
// CHECK:STDERR: fail_period_self_as_type.carbon:[[@LINE+7]]:13: error: cannot implicitly convert non-type value of type `.Self` to `type` [ConversionFailureNonTypeToFacet]
4648
// CHECK:STDERR: fn G() -> T;
@@ -161,7 +163,7 @@ fn F(U:! I(.Self) & J(.Self)) {
161163
F2(U.I1().J1().I1().J1().I1().J1());
162164
}
163165

164-
// --- fail_return_of_period_self_impls_interface.carbon
166+
// --- fail_todo_return_of_period_self_impls_interface.carbon
165167
library "[[@TEST_NAME]]";
166168

167169
interface I(T:! type) {
@@ -173,11 +175,35 @@ interface J(T:! type) {
173175
}
174176

175177
fn G(U:! I(.Self) where .Self impls J(.Self)) {
176-
// It's not possible to do compound lookup here. You would have to work with
177-
// the original type `U` instead.
178+
// Compound member lookup through a non-type value is possible for methods
179+
// which take a `self` parameter. But it's not possible for methods without
180+
// `self`. For those you need to go directly throug the type.
178181
// See: https://github.com/carbon-language/carbon-lang/issues/6025
182+
183+
// TODO: This step should work.
184+
//
185+
// CHECK:STDERR: fail_todo_return_of_period_self_impls_interface.carbon:[[@LINE+7]]:14: error: cannot implicitly convert expression of type `.Self` to `U` [ConversionFailure]
186+
// CHECK:STDERR: let u: U = U.I1();
187+
// CHECK:STDERR: ^~~~~~
188+
// CHECK:STDERR: fail_todo_return_of_period_self_impls_interface.carbon:[[@LINE+4]]:14: note: type `.Self` does not implement interface `Core.ImplicitAs(U)` [MissingImplInMemberAccessNote]
189+
// CHECK:STDERR: let u: U = U.I1();
190+
// CHECK:STDERR: ^~~~~~
191+
// CHECK:STDERR:
192+
let u: U = U.I1();
193+
// `u` is a non-type value. Can call methods with `self` through compound
194+
// member lookup, but can't call methods without `self`. See the
195+
// `compound_access_through_call_with_self_param.carbon` test for the former.
196+
//
197+
// CHECK:STDERR: fail_todo_return_of_period_self_impls_interface.carbon:[[@LINE+4]]:6: error: type `<type of J>` does not support qualified expressions [QualifiedExprUnsupported]
198+
// CHECK:STDERR: u.(J.J1)();
199+
// CHECK:STDERR: ^~~~
200+
// CHECK:STDERR:
201+
u.(J.J1)();
202+
203+
// This is the same as the above, since U.I1() returns a non-type value of
204+
// type `U`.
179205
//
180-
// CHECK:STDERR: fail_return_of_period_self_impls_interface.carbon:[[@LINE+4]]:11: error: type `<type of J>` does not support qualified expressions [QualifiedExprUnsupported]
206+
// CHECK:STDERR: fail_todo_return_of_period_self_impls_interface.carbon:[[@LINE+4]]:11: error: type `<type of J>` does not support qualified expressions [QualifiedExprUnsupported]
181207
// CHECK:STDERR: U.I1().(J.J1)();
182208
// CHECK:STDERR: ^~~~
183209
// CHECK:STDERR:
@@ -221,19 +247,6 @@ fn F(U:! I where .X = .Self) {
221247
let a: U = U.G();
222248
}
223249

224-
// --- fail_template_access.carbon
225-
library "[[@TEST_NAME]]";
226-
227-
// TODO: Improved error: no member named `I1` in `T` of type `type`.
228-
//
229-
// CHECK:STDERR: fail_template_access.carbon:[[@LINE+4]]:36: error: cannot evaluate type expression [TypeExprEvaluationFailure]
230-
// CHECK:STDERR: interface I(template T:! type, N:! T.I1) {
231-
// CHECK:STDERR: ^~~~
232-
// CHECK:STDERR:
233-
interface I(template T:! type, N:! T.I1) {
234-
let I1:! type;
235-
}
236-
237250
// --- fail_todo_nested_period_self.carbon
238251
library "[[@TEST_NAME]]";
239252

@@ -273,10 +286,10 @@ fn F(T:! I(.Self) where .A = ((I(.Self) where .B = {}) where .A = {}) and .B = {
273286
// CHECK:STDERR:
274287
T as (I(T) where .A = (I(T) where .A = {} and .B = {}));
275288
// CHECK:STDERR: fail_todo_nested_period_self.carbon:[[@LINE+4]]:3: error: cannot convert type `U` that implements `I(.Self) where .(I(.Self).B) = {} and .(I(.Self).A) = {}` into type implementing `I(T) where .(I(T).A) = {} and .(I(T).B) = {}` [ConversionFailureFacetToFacet]
276-
// CHECK:STDERR: U as (I(T) where .A ={} and .B = {});
277-
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
289+
// CHECK:STDERR: U as (I(T) where .A = {} and .B = {});
290+
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278291
// CHECK:STDERR:
279-
U as (I(T) where .A ={} and .B = {});
292+
U as (I(T) where .A = {} and .B = {});
280293
}
281294

282295
// --- todo_fail_nested_period_self_ambiguous.carbon
@@ -286,9 +299,9 @@ interface I(T:! type) {
286299
let A:! type;
287300
}
288301

289-
// TODO: This should be an error: The third `.Self` becomes undefined. It's not
290-
// referring to `T` but we need each explicit `.Self` to be replaced with
291-
// something at the end of the expression.
302+
// TODO: This should be an error: The third `.Self` becomes is not able to be
303+
// bound to anything unambiguous here, as it could refer to `T` or to something
304+
// later being constrained by `T.A`.
292305
fn F(T:! I(.Self) where .A = (I(.Self) where .A = I(.Self))) {}
293306

294307
// CHECK:STDOUT: --- period_self_param.carbon
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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/facet_types.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/template/fail_todo_template_access_assoc_const.carbon
10+
// TIP: To dump output, run:
11+
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/generic/template/fail_todo_template_access_assoc_const.carbon
12+
13+
library "[[@TEST_NAME]]";
14+
15+
// TODO: Improved error: no member named `I1` in `T` of type `type`.
16+
//
17+
// CHECK:STDERR: fail_todo_template_access_assoc_const.carbon:[[@LINE+4]]:36: error: cannot evaluate type expression [TypeExprEvaluationFailure]
18+
// CHECK:STDERR: interface I(template T:! type, N:! T.I1) {
19+
// CHECK:STDERR: ^~~~
20+
// CHECK:STDERR:
21+
interface I(template T:! type, N:! T.I1) {
22+
let I1:! type;
23+
}

0 commit comments

Comments
 (0)