mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
We checked that requirements inside the impl-as target interface were satisfied. But we also need to check that requirements coming from the constraint facet type, or named constraints that it targets, are satisfied.
308 lines
11 KiB
Plaintext
308 lines
11 KiB
Plaintext
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
|
|
//
|
|
// AUTOUPDATE
|
|
// TIP: To test this file alone, run:
|
|
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/where_expr/dot_self_impls.carbon
|
|
// TIP: To dump output, run:
|
|
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/where_expr/dot_self_impls.carbon
|
|
|
|
// --- compound_member_access_through_where_self_impls.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
fn FNonInstance();
|
|
fn FSelf(self);
|
|
}
|
|
|
|
interface J {
|
|
fn GNonInstance();
|
|
fn GSelf(self);
|
|
}
|
|
|
|
fn INotJ[T: I where .Self impls J](x: T) {
|
|
// Can access members of `I` using either kind of member access.
|
|
T.FNonInstance();
|
|
T.(I.FNonInstance)();
|
|
|
|
x.FNonInstance();
|
|
x.FSelf();
|
|
x.(I.FSelf)();
|
|
|
|
// Can still find members of `J` using compound member access,
|
|
// even though they are not available via `T.GNonInstance` or
|
|
// `x.GSelf`.
|
|
T.(J.GNonInstance)();
|
|
x.(J.GSelf)();
|
|
}
|
|
|
|
fn TypeNotJ[T: type where .Self impls J](x: T) {
|
|
T.(J.GNonInstance)();
|
|
x.(J.GSelf)();
|
|
}
|
|
|
|
// --- no_name_conflict_with_where_self_impls.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
fn F() -> ();
|
|
}
|
|
|
|
interface J {
|
|
fn F() -> {};
|
|
}
|
|
|
|
fn INotJ(generic T: I where .Self impls J) {
|
|
// Gets `T.(I.F)`. Doesn't consider `T.(J.F)`, so no ambiguity.
|
|
let unused x: () = T.F();
|
|
}
|
|
|
|
// --- fail_name_lookup_through_where_self_impls.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
fn F();
|
|
}
|
|
|
|
interface J {
|
|
fn G();
|
|
}
|
|
|
|
fn INotJ(generic T: I where .Self impls J) {
|
|
// CHECK:STDERR: fail_name_lookup_through_where_self_impls.carbon:[[@LINE+4]]:3: error: member name `G` not found in `I` [MemberNameNotFoundInSpecificScope]
|
|
// CHECK:STDERR: T.G();
|
|
// CHECK:STDERR: ^~~
|
|
// CHECK:STDERR:
|
|
T.G();
|
|
}
|
|
|
|
// --- fail_name_lookup_with_type.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface J {
|
|
fn G();
|
|
}
|
|
|
|
fn TypeNotJ(generic T: type where .Self impls J) {
|
|
// CHECK:STDERR: fail_name_lookup_with_type.carbon:[[@LINE+4]]:3: error: member name `G` not found [MemberNameNotFound]
|
|
// CHECK:STDERR: T.G();
|
|
// CHECK:STDERR: ^~~
|
|
// CHECK:STDERR:
|
|
T.G();
|
|
}
|
|
|
|
// --- fail_facet_type_simple_member_access.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface A {}
|
|
interface B { fn Bfn(); }
|
|
|
|
fn F(generic T: A & B) {
|
|
// CHECK:STDERR: fail_facet_type_simple_member_access.carbon:[[@LINE+4]]:6: error: member name `Bfn` not found in `A` [MemberNameNotFoundInSpecificScope]
|
|
// CHECK:STDERR: T.((A where .Self impls B).Bfn)();
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
T.((A where .Self impls B).Bfn)();
|
|
|
|
// CHECK:STDERR: fail_facet_type_simple_member_access.carbon:[[@LINE+4]]:3: error: member name `Bfn` not found in `A` [MemberNameNotFoundInSpecificScope]
|
|
// CHECK:STDERR: (A where .Self impls B).Bfn;
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
(A where .Self impls B).Bfn;
|
|
}
|
|
|
|
// --- fail_name_lookup_instance.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
fn FNonInstance();
|
|
fn FSelf(self);
|
|
}
|
|
|
|
interface J {
|
|
fn GNonInstance();
|
|
fn GSelf(self);
|
|
}
|
|
|
|
fn INotJ[T: I where .Self impls J](x: T) {
|
|
// CHECK:STDERR: fail_name_lookup_instance.carbon:[[@LINE+4]]:3: error: member name `GNonInstance` not found in `I` [MemberNameNotFoundInSpecificScope]
|
|
// CHECK:STDERR: x.GNonInstance();
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
x.GNonInstance();
|
|
|
|
// CHECK:STDERR: fail_name_lookup_instance.carbon:[[@LINE+4]]:3: error: member name `GSelf` not found in `I` [MemberNameNotFoundInSpecificScope]
|
|
// CHECK:STDERR: x.GSelf();
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR:
|
|
x.GSelf();
|
|
}
|
|
|
|
// --- compare_equal.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
class WrapType(T: type) {}
|
|
fn AssertSame[T: type](unused a: WrapType(T), unused b: WrapType(T)) {}
|
|
fn Type(generic T: type) -> WrapType(T) { return {}; }
|
|
|
|
interface I;
|
|
interface J;
|
|
interface K;
|
|
|
|
fn Test() {
|
|
AssertSame(Type(I), Type(I where .Self impls I));
|
|
AssertSame(Type(I), Type(I where .Self impls I & I));
|
|
AssertSame(Type(I & J), Type(J & I where .Self impls I));
|
|
AssertSame(Type(I & J), Type(J & I where .Self impls J));
|
|
AssertSame(Type(I & J), Type(J & I where .Self impls I & J));
|
|
AssertSame(Type(I & J where .Self impls K), Type(J & I where .Self impls I & K));
|
|
AssertSame(Type(I & J where .Self impls K), Type(J & I where .Self impls J & K));
|
|
AssertSame(Type(I & J where .Self impls K), Type(J & I where .Self impls K & I & J));
|
|
AssertSame(Type(I where .Self impls J & K), Type(I where .Self impls K & I & J));
|
|
}
|
|
|
|
interface I {}
|
|
interface J {}
|
|
interface K {}
|
|
|
|
// --- fail_todo_compare_equal_with_rewrite.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
class WrapType(T: type) {}
|
|
fn AssertSame[T: type](unused a: WrapType(T), unused b: WrapType(T)) {}
|
|
fn Type(generic T: type) -> WrapType(T) { return {}; }
|
|
|
|
interface I { let A: type; }
|
|
interface J { let B: type; }
|
|
|
|
// TODO: The `.Self` implied in `.A` contains all of the extended interfaces,
|
|
// which is different between these facet types at the point where `.A` is
|
|
// written. So the resulting facet types are different. We should drop
|
|
// interfaces from the rewrite constraint's LHS that don't apply so that we get
|
|
// a canonical representation of `.A` that is independent of the current state
|
|
// of `.Self` since `.A = ()` can not be written as, and is thus not equivalent
|
|
// to, `.Self.(I.A) = ()`.
|
|
|
|
fn Test() {
|
|
// TODO: This should pass.
|
|
// CHECK:STDERR: fail_todo_compare_equal_with_rewrite.carbon:[[@LINE+7]]:3: error: inconsistent deductions for value of generic parameter `T` [DeductionInconsistent]
|
|
// CHECK:STDERR: AssertSame(Type((I where .A = ()) & J),
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR: fail_todo_compare_equal_with_rewrite.carbon:[[@LINE-19]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
|
|
// CHECK:STDERR: fn AssertSame[T: type](unused a: WrapType(T), unused b: WrapType(T)) {}
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
AssertSame(Type((I where .A = ()) & J),
|
|
Type(I & J where .A = ()));
|
|
// TODO: This should pass.
|
|
// CHECK:STDERR: fail_todo_compare_equal_with_rewrite.carbon:[[@LINE+7]]:3: error: inconsistent deductions for value of generic parameter `T` [DeductionInconsistent]
|
|
// CHECK:STDERR: AssertSame(Type(I & (J where .B = {})),
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR: fail_todo_compare_equal_with_rewrite.carbon:[[@LINE-29]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
|
|
// CHECK:STDERR: fn AssertSame[T: type](unused a: WrapType(T), unused b: WrapType(T)) {}
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
AssertSame(Type(I & (J where .B = {})),
|
|
Type(I & J where .B = {}));
|
|
|
|
// TODO: This should pass.
|
|
// CHECK:STDERR: fail_todo_compare_equal_with_rewrite.carbon:[[@LINE+7]]:3: error: inconsistent deductions for value of generic parameter `T` [DeductionInconsistent]
|
|
// CHECK:STDERR: AssertSame(Type((I where .A = ()) & (J where .B = {})),
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR: fail_todo_compare_equal_with_rewrite.carbon:[[@LINE-40]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
|
|
// CHECK:STDERR: fn AssertSame[T: type](unused a: WrapType(T), unused b: WrapType(T)) {}
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
AssertSame(Type((I where .A = ()) & (J where .B = {})),
|
|
Type(I & J where .A = () and .B = {}));
|
|
}
|
|
|
|
// --- fail_compare_not_equal.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
class WrapType(T: type) {}
|
|
fn Same[T: type](unused a: WrapType(T), unused b: WrapType(T)) {}
|
|
fn Type(generic T: type) -> WrapType(T) { return {}; }
|
|
|
|
interface I {}
|
|
interface J {}
|
|
|
|
fn Test() {
|
|
// CHECK:STDERR: fail_compare_not_equal.carbon:[[@LINE+7]]:3: error: inconsistent deductions for value of generic parameter `T` [DeductionInconsistent]
|
|
// CHECK:STDERR: Same(Type(I where .Self impls J), Type(J where .Self impls I));
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR: fail_compare_not_equal.carbon:[[@LINE-10]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
|
|
// CHECK:STDERR: fn Same[T: type](unused a: WrapType(T), unused b: WrapType(T)) {}
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
Same(Type(I where .Self impls J), Type(J where .Self impls I));
|
|
}
|
|
|
|
// --- todo_fail_compare_not_equal_with_same_type.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
class WrapType(T: type) {}
|
|
fn Same[T: type](unused a: WrapType(T), unused b: WrapType(T)) {}
|
|
fn Type(generic T: type) -> WrapType(T) { return {}; }
|
|
|
|
interface I { let A: type; }
|
|
interface J { let B: type; }
|
|
|
|
fn Test() {
|
|
// The first `.A` has a `.Self` of type `I`. The second contains a `.Self` of
|
|
// type `I & J`. That makes the two constaints `.A == ()` have different
|
|
// constant values, so these are different facet types.
|
|
//
|
|
// TODO: This should fail. We don't store same-type constraints in the facet type yet.
|
|
Same(Type((I where .A == ()) & J), Type(I & J where .A == ()));
|
|
}
|
|
|
|
// --- impl_as.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
class C {}
|
|
|
|
interface I {}
|
|
interface J { let T: type; }
|
|
|
|
// Interfaces to the right of the `where` don't interfere with the
|
|
// "can only impl a facet type with a single interface" rule. Only
|
|
// the interface being implemented needs to have all of its
|
|
// associated constants set.
|
|
impl {.a: C} as I where .Self impls J;
|
|
impl {.b: C} as J where .Self impls I and .T = ();
|
|
|
|
// The requirements after `where` must be met before we define the above impls.
|
|
impl {.a: C} as J where .T = () {}
|
|
impl {.a: C} as I where .Self impls J {}
|
|
impl {.b: C} as I {}
|
|
impl {.b: C} as J where .Self impls I and .T = () {}
|
|
|
|
// --- impl_with_rewrite_of_interface_not_being_implemented.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let A: type; }
|
|
interface J { let A: type; }
|
|
|
|
class C {}
|
|
|
|
// Implementation of `C as J`.
|
|
impl C as J where .A = {} {}
|
|
|
|
// Requirement of implementing J with `.A = A`.
|
|
constraint NeedJ(A: type) {
|
|
require impls J where .A = A;
|
|
}
|
|
|
|
// This is an implementation of `I` with `I.A = ()`. The requirement
|
|
// that `C` also impls `J where .A = {}` is an additional constraint
|
|
// that must be satisfied (and is satisfied by the impl above, though
|
|
// that currently isn't checked), but doesn't affect `C as I`.
|
|
impl C as I where .A = () and .Self impls NeedJ({}) {}
|
|
|
|
let x: C.(I.A) = ();
|
|
let y: C.(J.A) = {};
|