mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
In order to verify rewrite constraints at the end of `LookupImplWitness()` we need to replace references to associated constants in the query facet type with values that come from the query's self. To do this, we find any `ImplWitnessAccess` that is a reference to `.Self` and replace its witness with the witness found through the impl lookup process, if the interfaces match. This allows the `ImplWitnessAccess` to resolve to a concrete value if that witness was concrete. Then we just need to compare that for each rewrite constraint the lhs and rhs are the same constant value. If they differ, the self provided a different value for one side (either through its own facet value constraints or through an associated impl), or the self did not provide a value at all. For now, only .Self references in the top-level facet type are rewritten. Nested facet types are not, even if they contain a .Self reference up to the top level facet value. This will be addressed by adding numbering to the EntityName of of .Self in a BindSymbolicName. See the third model in https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0 for the plan. For now, there is a TODO addressing this.
1362 lines
47 KiB
Plaintext
1362 lines
47 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/facet_types.carbon
|
|
//
|
|
// AUTOUPDATE
|
|
// TIP: To test this file alone, run:
|
|
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/validate_rewrite_constraints.carbon
|
|
// TIP: To dump output, run:
|
|
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/validate_rewrite_constraints.carbon
|
|
|
|
// --- facet_value.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
fn F(T:! I where .X = ()) {}
|
|
|
|
fn G(T:! I where .X = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- generic_interface_facet_value.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I(T:! type) { let X:! type; }
|
|
|
|
class C;
|
|
final impl forall [T:! type] T as I(()) where .X = () {}
|
|
final impl forall [T:! type] T as I({}) where .X = {} {}
|
|
|
|
fn F(U:! type, T:! I(U) where .X = ()) {}
|
|
fn G() {
|
|
F((), C);
|
|
}
|
|
|
|
// --- fail_generic_interface_facet_value_wrong_specific_impl.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I(T:! type) { let X:! type; }
|
|
|
|
class C;
|
|
final impl forall [T:! type] T as I(()) where .X = () {}
|
|
final impl forall [T:! type] T as I({}) where .X = {} {}
|
|
|
|
fn F(U:! type, T:! I(U) where .X = ()) {}
|
|
fn G() {
|
|
// This finds the impl where `.X = {}`, but F requires that `.X = ()`.
|
|
//
|
|
// CHECK:STDERR: fail_generic_interface_facet_value_wrong_specific_impl.carbon:[[@LINE+7]]:3: error: cannot convert type `C` into type implementing `I({}) where .(I({}).X) = ()` [ConversionFailureTypeToFacet]
|
|
// CHECK:STDERR: F({}, C);
|
|
// CHECK:STDERR: ^~~~~~~~
|
|
// CHECK:STDERR: fail_generic_interface_facet_value_wrong_specific_impl.carbon:[[@LINE-7]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
|
|
// CHECK:STDERR: fn F(U:! type, T:! I(U) where .X = ()) {}
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
F({}, C);
|
|
}
|
|
|
|
// --- dependent_rules.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
interface J { let Y:! type; }
|
|
|
|
fn F(T:! I & J where .X = .Y) {
|
|
// Allowed since `T impls I`, `T impls J`, and has constraint providing
|
|
// T.(I.X) = T.(J.Y)`.
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_convert.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
fn F(T:! I where .X = {.a: (), .b: {}}) {}
|
|
|
|
fn H() {
|
|
class C;
|
|
impl C as I where .X = {.b: {}, .a: ()} {}
|
|
// CHECK:STDERR: fail_convert.carbon:[[@LINE+7]]:3: error: cannot convert type `C` into type implementing `I where .(I.X) = {.a: (), .b: {}}` [ConversionFailureTypeToFacet]
|
|
// CHECK:STDERR: F(C);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_convert.carbon:[[@LINE-8]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = {.a: (), .b: {}}) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(C);
|
|
}
|
|
|
|
fn G(T:! I where .X = {.b: {}, .a: ()}) {
|
|
// CHECK:STDERR: fail_convert.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I where .(I.X) = {.b: {}, .a: ()}` into type implementing `I where .(I.X) = {.a: (), .b: {}}` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_convert.carbon:[[@LINE-19]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = {.a: (), .b: {}}) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_todo_dependent_rules_compound.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
interface J { let Y:! type; }
|
|
|
|
// CHECK:STDERR: fail_todo_dependent_rules_compound.carbon:[[@LINE+8]]:23: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
|
|
// CHECK:STDERR: fn F(T:! I & J where .(I.X) = .(J.Y)) {
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
// CHECK:STDERR: fail_todo_dependent_rules_compound.carbon:[[@LINE+4]]:23: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
|
|
// CHECK:STDERR: fn F(T:! I & J where .(I.X) = .(J.Y)) {
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
fn F(T:! I & J where .(I.X) = .(J.Y)) {
|
|
// Allowed since `T impls I`, `T impls J`, and has constraint providing
|
|
// T.(I.X) = T.(J.Y)`.
|
|
F(T);
|
|
}
|
|
|
|
// --- parameterized_interface.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I(T:! type) { let X:! type; }
|
|
|
|
final impl forall [J:! I(()) where .X = ()] J as I({}) where .X = {} {}
|
|
|
|
fn F(T:! I({}) where .X = {}) {}
|
|
|
|
fn G(T:! I(()) where .X = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_todo_parameterized_interface_compound.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I(T:! type) { let X:! type; }
|
|
|
|
final impl forall [J:! I(())] J as I({}) where .X = {} {}
|
|
|
|
// CHECK:STDERR: fail_todo_parameterized_interface_compound.carbon:[[@LINE+8]]:31: error: expected identifier or `Self` after `.` [ExpectedIdentifierOrSelfAfterPeriod]
|
|
// CHECK:STDERR: fn F(T:! I(()) & I({}) where .(I(()).X) = () and .(I({}).X) = {}) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
// CHECK:STDERR: fail_todo_parameterized_interface_compound.carbon:[[@LINE+4]]:31: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
|
|
// CHECK:STDERR: fn F(T:! I(()) & I({}) where .(I(()).X) = () and .(I({}).X) = {}) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
fn F(T:! I(()) & I({}) where .(I(()).X) = () and .(I({}).X) = {}) {}
|
|
|
|
fn G(T:! I(()) where .X = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_parameterized_interface_with_wrong_where_in_impl_deduction.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I(T:! type) { let X:! type; }
|
|
|
|
final impl forall [J:! I(()) where .X = {}] J as I({}) where .X = {} {}
|
|
|
|
fn F(T:! I({}) where .X = {}) {}
|
|
|
|
fn G(T:! I(()) where .X = ()) {
|
|
// CHECK:STDERR: fail_parameterized_interface_with_wrong_where_in_impl_deduction.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I(()) where .(I(()).X) = ()` into type implementing `I({}) where .(I({}).X) = {}` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_parameterized_interface_with_wrong_where_in_impl_deduction.carbon:[[@LINE-6]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I({}) where .X = {}) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- source_rhs_is_assoc_constant.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X1:! type;
|
|
let X2:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X1 = () and .X2 = ()) {}
|
|
|
|
fn G() {
|
|
class C;
|
|
impl C as I where .X1 = .X2 and .X2 = () {}
|
|
F(C);
|
|
}
|
|
|
|
fn H(T:! I where .X1 = .X2 and .X2 = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- target_rhs_is_assoc_constant.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X1:! type;
|
|
let X2:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X1 = .X2 and .X2 = ()) {}
|
|
|
|
fn G() {
|
|
class C;
|
|
impl C as I where .X1 = () and .X2 = () {}
|
|
F(C);
|
|
}
|
|
|
|
fn H(T:! I where .X1 = () and .X2 = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- both_rhs_is_assoc_constant.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X1:! type;
|
|
let X2:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X1 = .X2 and .X2 = ()) {}
|
|
|
|
fn G() {
|
|
class C1;
|
|
impl C1 as I where .X1 = .X2 and .X2 = () {}
|
|
F(C1);
|
|
|
|
class C2;
|
|
impl C2 as I where .X1 = () and .X2 = .X1 {}
|
|
F(C2);
|
|
}
|
|
|
|
fn H1(T:! I where .X1 = .X2 and .X2 = ()) {
|
|
F(T);
|
|
}
|
|
|
|
fn H2(T:! I where .X1 = () and .X2 = .X1) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_error_in_witness_table.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X1:! type;
|
|
let X2:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X1 = .X2) {}
|
|
|
|
class C;
|
|
// .X2 is not set in the impl definition, so its value is an ErrorInst
|
|
// in the impl's witness table.
|
|
//
|
|
// CHECK:STDERR: fail_error_in_witness_table.carbon:[[@LINE+7]]:1: error: associated constant X2 not given a value in impl of interface I [ImplAssociatedConstantNeedsValue]
|
|
// CHECK:STDERR: impl C as I where .X1 = () {}
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR: fail_error_in_witness_table.carbon:[[@LINE-12]]:7: note: associated constant declared here [AssociatedConstantHere]
|
|
// CHECK:STDERR: let X2:! type;
|
|
// CHECK:STDERR: ^~~~~~~~~
|
|
// CHECK:STDERR:
|
|
impl C as I where .X1 = () {}
|
|
|
|
fn G() {
|
|
// CHECK:STDERR: fail_error_in_witness_table.carbon:[[@LINE+7]]:3: error: cannot convert type `C` into type implementing `I where .(I.X1) = .(I.X2)` [ConversionFailureTypeToFacet]
|
|
// CHECK:STDERR: F(C);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_error_in_witness_table.carbon:[[@LINE-19]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X1 = .X2) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(C);
|
|
}
|
|
|
|
// --- impl_provides_rewrite_requirements.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {}
|
|
interface J { let Y:! type; }
|
|
|
|
class C;
|
|
|
|
final impl forall [T:! I] T as J where .Y = C {}
|
|
|
|
fn F(T:! I & J where .Y = C) {}
|
|
fn G(T:! I) {
|
|
F(T);
|
|
}
|
|
|
|
// --- facet_provides_rewrite_requirements.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {}
|
|
interface J { let Y:! type; }
|
|
|
|
class C;
|
|
|
|
final impl forall [T:! J] T as I {}
|
|
|
|
fn F(T:! I & J where .Y = C) {}
|
|
fn G(T:! J where .Y = C) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_non_final_impl_deduce.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
impl forall [U:! type] U as I where .X = () {}
|
|
|
|
fn F(T:! I where .X = ()) {}
|
|
|
|
class C(T:! type);
|
|
|
|
fn G(T:! type) {
|
|
// The type `C(T)` is generic so that the resulting impl witness will not be
|
|
// effectively final.
|
|
//
|
|
// CHECK:STDERR: fail_non_final_impl_deduce.carbon:[[@LINE+7]]:3: error: cannot convert type `C(T)` into type implementing `I where .(I.X) = ()` [ConversionFailureTypeToFacet]
|
|
// CHECK:STDERR: F(C(T));
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_non_final_impl_deduce.carbon:[[@LINE-11]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = ()) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(C(T));
|
|
}
|
|
|
|
// --- fail_non_final_impl_explicit.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
impl forall [U:! type] U as I where .X = () {}
|
|
|
|
class C(T:! type);
|
|
|
|
fn F(T:! type) {
|
|
// The type `C(T)` is generic so that the resulting impl witness will not be
|
|
// effectively final.
|
|
//
|
|
// CHECK:STDERR: fail_non_final_impl_explicit.carbon:[[@LINE+4]]:3: error: cannot convert type `C(T)` into type implementing `I where .(I.X) = ()` [ConversionFailureTypeToFacet]
|
|
// CHECK:STDERR: C(T) as (I where .X = ());
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
C(T) as (I where .X = ());
|
|
}
|
|
|
|
// --- concrete_query_non_final_impl_deduce.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
impl forall [U:! type] U as I where .X = () {}
|
|
|
|
fn F(T:! I where .X = ()) {}
|
|
|
|
fn G() {
|
|
class C;
|
|
F(C);
|
|
}
|
|
|
|
// --- concrete_query_non_final_impl_explicit_as.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
impl forall [U:! type] U as I where .X = () {}
|
|
|
|
fn F() {
|
|
class C;
|
|
C as (I where .X = ());
|
|
}
|
|
|
|
// --- final_impl_deduce.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
final impl forall [U:! type] U as I where .X = () {}
|
|
|
|
fn F(T:! I where .X = ()) {}
|
|
|
|
fn G() {
|
|
class C;
|
|
F(C);
|
|
}
|
|
|
|
// --- final_impl_explicit_as.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
final impl forall [U:! type] U as I where .X = () {}
|
|
|
|
fn F() {
|
|
class C;
|
|
C as (I where .X = ());
|
|
}
|
|
|
|
// --- concrete_specialization_impl_deduce.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
class C;
|
|
impl C as I where .X = () {}
|
|
|
|
fn F(T:! I where .X = ()) {}
|
|
fn G() {
|
|
F(C);
|
|
}
|
|
|
|
// --- concrete_specialization_impl_explicit_as.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
|
|
class C;
|
|
impl C as I where .X = () {}
|
|
|
|
fn F() {
|
|
C as (I where .X = ());
|
|
}
|
|
|
|
// --- rewrite_value_in_class_param.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
class C(T:! type);
|
|
|
|
fn F(T:! I where .X = C(.Y)) {}
|
|
|
|
fn G(T:! I where .X = C(()) and .Y = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_wrong_rewrite_value_in_class_param.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
class C(T:! type);
|
|
|
|
fn F(T:! I where .X = C(.Y)) {}
|
|
|
|
fn G(T:! I where .X = C(()) and .Y = {}) {
|
|
// CHECK:STDERR: fail_wrong_rewrite_value_in_class_param.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I where .(I.X) = C(()) and .(I.Y) = {}` into type implementing `I where .(I.X) = C(.(I.Y))` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_wrong_rewrite_value_in_class_param.carbon:[[@LINE-6]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = C(.Y)) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- function_in_interface_ignored.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
fn F();
|
|
}
|
|
|
|
fn F(T:! I where .X = ()) {}
|
|
|
|
fn G(T:! I where .X = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- function_as_rewrite_value.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! X;
|
|
fn A();
|
|
}
|
|
|
|
fn F(T:! I where .Y = .A) {}
|
|
|
|
fn G(T:! I where .Y = .A) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_wrong_function_as_rewrite_value.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! X;
|
|
fn A();
|
|
fn B();
|
|
}
|
|
|
|
fn F(T:! I where .Y = .A) {}
|
|
|
|
fn G(T:! I where .Y = .B) {
|
|
// CHECK:STDERR: fail_wrong_function_as_rewrite_value.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I where .(I.Y) = .(I.B)` into type implementing `I where .(I.Y) = .(I.A)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_wrong_function_as_rewrite_value.carbon:[[@LINE-6]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .Y = .A) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_wrong_function_as_rewrite_value_in_other_interface.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! X;
|
|
fn A();
|
|
}
|
|
|
|
interface J {
|
|
let J1:! type;
|
|
let J2:! type;
|
|
// B has the same index in J as A does in I, ensuring the index is not enough
|
|
// for comparing them.
|
|
fn B();
|
|
}
|
|
|
|
fn F(T:! I & J where .Y = .A) {}
|
|
|
|
fn G(T:! I & J where .Y = .B) {
|
|
// CHECK:STDERR: fail_wrong_function_as_rewrite_value_in_other_interface.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I & J where .(I.Y) = .(J.B)` into type implementing `I & J where .(I.Y) = .(I.A)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_wrong_function_as_rewrite_value_in_other_interface.carbon:[[@LINE-6]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I & J where .Y = .A) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- recursive_facet.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I { let X:! type; }
|
|
interface K(Y:! type) { }
|
|
|
|
fn F(T:! I where .X = {.k: K(I where .X = ())}) {}
|
|
|
|
fn G(T:! I where .X = {.k: K(I where .X = ())}) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_facet_type_concrete_types_match_blanket_impl_concrete_types.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface A { let X:! type; }
|
|
interface B { let Y:! type; }
|
|
|
|
interface C(BB:! B) { let AX:! type; let BY:! type; }
|
|
|
|
impl forall [AA:! A, BB:! B] AA as C(BB) where .AX = () and .BY = {} {}
|
|
|
|
fn F(AA:! A where .X = (), BB:! B where .Y = {}) {
|
|
// The types match but there may be a specialization that specifies different
|
|
// types and would be prefered for a specific `AA` or `BB`.
|
|
//
|
|
// CHECK:STDERR: fail_facet_type_concrete_types_match_blanket_impl_concrete_types.carbon:[[@LINE+4]]:3: error: cannot convert type `AA` that implements `A where .(A.X) = ()` into type implementing `C(BB as B) where .(C(BB as B).AX) = () and .(C(BB as B).BY) = {}` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: AA as (C(BB) where .AX = () and .BY = {});
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
AA as (C(BB) where .AX = () and .BY = {});
|
|
}
|
|
|
|
// --- fail_facet_type_concrete_types_become_blank_impl_types.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface A { let X:! type; }
|
|
interface B { let Y:! type; }
|
|
|
|
interface C(BB:! B) { let AX:! type; let BY:! type; }
|
|
|
|
impl forall [AA:! A, BB:! B] AA as C(BB) where .AX = AA.X and .BY = BB.Y {}
|
|
|
|
fn F(AA:! A where .X = (), BB:! B where .Y = {}) {
|
|
// The types match but there may be a specialization that specifies different
|
|
// types and would be prefered for a specific `AA` or `BB`.
|
|
//
|
|
// CHECK:STDERR: fail_facet_type_concrete_types_become_blank_impl_types.carbon:[[@LINE+4]]:3: error: cannot convert type `AA` that implements `A where .(A.X) = ()` into type implementing `C(BB as B) where .(C(BB as B).AX) = () and .(C(BB as B).BY) = {}` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: AA as (C(BB) where .AX = () and .BY = {});
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
AA as (C(BB) where .AX = () and .BY = {});
|
|
}
|
|
|
|
// --- facet_type_concrete_types_match_final_blanket_impl_concrete_types.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface A { let X:! type; }
|
|
interface B { let Y:! type; }
|
|
|
|
interface C(BB:! B) { let AX:! type; let BY:! type; }
|
|
|
|
final impl forall [AA:! A, BB:! B] AA as C(BB) where .AX = () and .BY = {} {}
|
|
|
|
fn F(AA:! A where .X = (), BB:! B where .Y = {}) {
|
|
AA as (C(BB) where .AX = () and .BY = {});
|
|
}
|
|
|
|
// --- facet_type_concrete_types_become_final_blanket_impl_types.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface A { let X:! type; }
|
|
interface B { let Y:! type; }
|
|
|
|
interface C(BB:! B) { let AX:! type; let BY:! type; }
|
|
|
|
final impl forall [AA:! A, BB:! B] AA as C(BB) where .AX = AA.X and .BY = BB.Y {}
|
|
|
|
fn F(AA:! A where .X = (), BB:! B where .Y = {}) {
|
|
AA as (C(BB) where .AX = () and .BY = {});
|
|
}
|
|
|
|
// --- fail_facet_type_concrete_types_become_final_blanket_impl_types_wrong_types.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface A { let X:! type; }
|
|
interface B { let Y:! type; }
|
|
|
|
interface C(BB:! B) { let AX:! type; let BY:! type; }
|
|
|
|
final impl forall [AA:! A, BB:! B] AA as C(BB) where .AX = AA.X and .BY = BB.Y {}
|
|
|
|
fn F(AA:! A where .X = (), BB:! B where .Y = {}) {
|
|
// CHECK:STDERR: fail_facet_type_concrete_types_become_final_blanket_impl_types_wrong_types.carbon:[[@LINE+4]]:3: error: cannot convert type `AA` that implements `A where .(A.X) = ()` into type implementing `C(BB as B) where .(C(BB as B).AX) = {} and .(C(BB as B).BY) = ()` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: AA as (C(BB) where .AX = {} and .BY = ());
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
AA as (C(BB) where .AX = {} and .BY = ());
|
|
}
|
|
|
|
// --- chain_in_target.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X1:! type;
|
|
let X2:! type;
|
|
let X3:! type;
|
|
}
|
|
|
|
class C(T:! type);
|
|
|
|
fn F(T:! I where .X1 = .X3 and .X2 = C(.X3) and .X3 = ()) {}
|
|
|
|
fn G(T:! I where .X1 = () and .X2 = C(()) and .X3 = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- chain_in_source.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X1:! type;
|
|
let X2:! type;
|
|
let X3:! type;
|
|
}
|
|
|
|
class C(T:! type);
|
|
|
|
fn F(T:! I where .X1 = () and .X2 = C(()) and .X3 = .X1) {}
|
|
|
|
fn G(T:! I where .X1 = .X3 and .X2 = C(.X1) and .X3 = ()) {
|
|
F(T);
|
|
}
|
|
|
|
// --- reference_other_facet_value.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X1:! type;
|
|
let X2:! type;
|
|
}
|
|
|
|
fn F(U:! I where .X1 = {}, T:! I where .X1 = () and .X2 = U.X1) {}
|
|
|
|
fn G(U:! I where .X1 = {} and .X2 = (), T:! I where .X1 = U.X2 and .X2 = {}) {
|
|
F(U, T);
|
|
}
|
|
|
|
// --- fail_todo_value_through_self_value.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
// TODO: This should not be diagnosed.
|
|
//
|
|
// CHECK:STDERR: fail_todo_value_through_self_value.carbon:[[@LINE+7]]:12: error: associated constant has incomplete type `I` [IncompleteTypeInAssociatedConstantDecl]
|
|
// CHECK:STDERR: let X1:! I;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR: fail_todo_value_through_self_value.carbon:[[@LINE-6]]:1: note: interface is currently being defined [InterfaceIncompleteWithinDefinition]
|
|
// CHECK:STDERR: interface I {
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
let X1:! I;
|
|
let X2:! type;
|
|
let X3:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X1 = .Self and .X2 = .X1.X3 and .X3 = ());
|
|
|
|
fn G(T:! I where .X1 = .Self and .X2 = () and .X3 = ()) {
|
|
F(T);
|
|
}
|
|
|
|
fn H(T:! I where .X1 = .Self and .X2 = .X1.X3 and .X3 = ()) {
|
|
G(T);
|
|
}
|
|
|
|
// --- associated_constant_is_facet_type_of_same_interface.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let A:! type;
|
|
let X:! type;
|
|
}
|
|
|
|
class C;
|
|
|
|
// This looks for a bug where `.Self.A` resolves to `C` from `.T.A` in the
|
|
// incoming facet value, which is incorrect. It should be `.T.X.A` which
|
|
// resolves to `{}`.
|
|
fn F(U:! I where .X = (I where .A = {})) {}
|
|
|
|
fn G(T:! I where .X = (I where .A = {}) and .A = C) {
|
|
F(T);
|
|
}
|
|
|
|
// --- rewrite_requires_subst_in_rhs.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
class C(T:! type);
|
|
|
|
fn F(T:! I where .X = C(.Y)) {}
|
|
|
|
fn G(T:! I where .X = C({}) and .Y = {}) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_todo_rewrite_requires_subst_in_nested_facet_type.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I(T:! type) {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
class C;
|
|
|
|
fn F(T:! I(C) where .X = (I(.Y) where .Y = ())) {}
|
|
|
|
fn G(T:! I(C) where .X = (I({}) where .Y = ()) and .Y = {}) {
|
|
// TODO: The T in G should match the T in F, once the .Self reference to the
|
|
// top level facet value in `I(.Y)` is correctly substituted by tracking that
|
|
// it is a .Self reference to the top level Self.
|
|
// CHECK:STDERR: fail_todo_rewrite_requires_subst_in_nested_facet_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I(C) where .(I(C).X) = I({}) where .(I({}).Y) = () and .(I(C).Y) = {}` into type implementing `I(C) where .(I(C).X) = I(.(I(C).Y)) where .(I(.(I(C).Y)).Y) = ()` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_todo_rewrite_requires_subst_in_nested_facet_type.carbon:[[@LINE-9]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I(C) where .X = (I(.Y) where .Y = ())) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
fn G2(T:! I(C) where .X = (I(.Y) where .Y = ()) and .Y = {}) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_rewrite_requires_subst_in_nested_facet_type_types_differ.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I(T:! type) {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
fn F(T:! I({}) where .X = (I(.Y) where .X = ())) {}
|
|
|
|
// I(.Y) is I({}) which doesn't match I(()).
|
|
fn G(T:! I({}) where .X = (I(()) where .X = ()) and .Y = {}) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_facet_type_types_differ.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I({}) where .(I({}).X) = I(()) where .(I(()).X) = () and .(I({}).Y) = {}` into type implementing `I({}) where .(I({}).X) = I(.(I({}).Y)) where .(I(.(I({}).Y)).X) = ()` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_facet_type_types_differ.carbon:[[@LINE-7]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I({}) where .X = (I(.Y) where .X = ())) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- facet_type_in_assoc_constant.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X = (I where .X = () and .Y = ())) {}
|
|
|
|
fn G(T:! I where .X = (I where .X = .Y and .Y = ())) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_facet_type_in_assoc_constant_differs.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
let Z:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X = (I where .X = .Y)) {}
|
|
|
|
fn G(T:! I where .X = (I where .X = () and .Y = () and .Z = {})) {
|
|
// CHECK:STDERR: fail_facet_type_in_assoc_constant_differs.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.X) = () and .(I.Y) = () and .(I.Z) = {}` into type implementing `I where .(I.X) = I where .(I.X) = .(I.Y)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_facet_type_in_assoc_constant_differs.carbon:[[@LINE-6]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .X = .Y)) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- nested_facet_type_in_assoc_constant.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
let Z:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X = (I where .Y = (I where .X = () and .Y = ()))) {}
|
|
|
|
fn G(T:! I where .X = (I where .Y = (I where .X = .Y and .Y = ()))) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_nested_facet_type_assigns_same_assoc_constant.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
fn F(T:! I where .Y = ()) {}
|
|
|
|
// The `.Y = ()` is on a different `.Self` than `T` (an unattached self), so
|
|
// should not satisfy `F`.
|
|
fn G(T:! I where .X = (I where .Y = ())) {
|
|
// CHECK:STDERR: fail_nested_facet_type_assigns_same_assoc_constant.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.Y) = ()` into type implementing `I where .(I.Y) = ()` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_assigns_same_assoc_constant.carbon:[[@LINE-8]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .Y = ()) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_nested_facet_type_in_assoc_constant_differs.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
let Z:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X = (I where .Y = (I where .X = .Y))) {}
|
|
|
|
// `.X = .Y` does not match `.X = () and .Y = ()` as they are different resolved
|
|
// facet types.
|
|
fn G(T:! I where .X = (I where .Y = (I where .X = () and .Y = ()))) {
|
|
// CHECK:STDERR: fail_nested_facet_type_in_assoc_constant_differs.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.Y) = I where .(I.X) = () and .(I.Y) = ()` into type implementing `I where .(I.X) = I where .(I.Y) = I where .(I.X) = .(I.Y)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_in_assoc_constant_differs.carbon:[[@LINE-8]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// The extra .Z rewrite makes a different resolved facet type which does not
|
|
// match.
|
|
fn G2(T:! I where .X = (I where .Y = (I where .X = .Y and .Z = {}))) {
|
|
// CHECK:STDERR: fail_nested_facet_type_in_assoc_constant_differs.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.Y) = I where .(I.X) = .(I.Y) and .(I.Z) = {}` into type implementing `I where .(I.X) = I where .(I.Y) = I where .(I.X) = .(I.Y)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_in_assoc_constant_differs.carbon:[[@LINE-21]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_nested_facet_type_from_constant.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
|
|
// References to named constants in a facet type don't work at all. If they did,
|
|
// then when the `Constant` facet type is put into the RHS of a rewrite
|
|
// constraint, its references to `.Self` must be modified to not refer to the
|
|
// top level `.Self` which is `T`. If done correctly, they will match the
|
|
// `.Self` references in the same position in the parameter of `F`. If not, the
|
|
// `.X` within becomes self-referential and makes a cycle.
|
|
|
|
fn G1() {
|
|
let Constant:! type = I where .X = .Y;
|
|
|
|
fn G(T:! I where .X = (I where .Y = (Constant, ))) {
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE+7]]:5: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.Y) = (Constant,)` into type implementing `I where .(I.X) = I where .(I.Y) = (I where .(I.X) = .(I.Y),)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE-16]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
}
|
|
|
|
fn G2() {
|
|
let Constant:! type = (I where .X = .Y, );
|
|
|
|
fn G(T:! I where .X = (I where .Y = Constant)) {
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE+7]]:5: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.Y) = Constant` into type implementing `I where .(I.X) = I where .(I.Y) = (I where .(I.X) = .(I.Y),)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE-31]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
}
|
|
|
|
fn G3() {
|
|
let Constant:! type = I where .Y = (I where .X = .Y, );
|
|
|
|
fn G(T:! I where .X = Constant) {
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE+7]]:5: error: cannot convert type `T` that implements `I where .(I.X) = Constant` into type implementing `I where .(I.X) = I where .(I.Y) = (I where .(I.X) = .(I.Y),)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE-46]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
}
|
|
|
|
fn G4() {
|
|
let Constant2:! type = (I where .X = .Y, );
|
|
let Constant:! type = Constant2;
|
|
|
|
fn G(T:! I where .X = (I where .Y = Constant)) {
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE+7]]:5: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.Y) = Constant` into type implementing `I where .(I.X) = I where .(I.Y) = (I where .(I.X) = .(I.Y),)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE-62]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
}
|
|
|
|
fn G5() {
|
|
let Constant2:! type = I where .X = .Y;
|
|
let Constant:! type = (Constant2, );
|
|
|
|
fn G(T:! I where .X = (I where .Y = Constant)) {
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE+7]]:5: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.Y) = Constant` into type implementing `I where .(I.X) = I where .(I.Y) = (I where .(I.X) = .(I.Y),)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE-78]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
}
|
|
|
|
fn G6() {
|
|
let Constant2:! type = (I where .X = .Y, );
|
|
let Constant:! type = I where .Y = Constant2;
|
|
|
|
fn G(T:! I where .X = Constant) {
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE+7]]:5: error: cannot convert type `T` that implements `I where .(I.X) = Constant` into type implementing `I where .(I.X) = I where .(I.Y) = (I where .(I.X) = .(I.Y),)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant.carbon:[[@LINE-94]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
}
|
|
|
|
// ---fail_nested_facet_type_from_constant_differs.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
|
|
fn G1() {
|
|
let Constant:! type = I where .X = () and .Y = ();
|
|
|
|
fn G(T:! I where .X = (I where .Y = (Constant, ))) {
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant_differs.carbon:[[@LINE+7]]:5: error: cannot convert type `T` that implements `I where .(I.X) = I where .(I.Y) = (Constant,)` into type implementing `I where .(I.X) = I where .(I.Y) = (I where .(I.X) = .(I.Y),)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_nested_facet_type_from_constant_differs.carbon:[[@LINE-9]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .X = (I where .Y = (I where .X = .Y, ))) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
}
|
|
|
|
// --- rewrite_requires_subst_in_nested_access_of_self.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let I1:! type;
|
|
let I2:! type;
|
|
}
|
|
|
|
interface J {
|
|
let J1:! I;
|
|
}
|
|
|
|
interface K {
|
|
let K1:! J;
|
|
}
|
|
|
|
fn F(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I1 = (.K1.J1).I2) {}
|
|
|
|
fn G(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I1 = .I2) {
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_rewrite_requires_subst_in_nested_access_of_self_wrong_type.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let I1:! type;
|
|
let I2:! type;
|
|
}
|
|
|
|
interface J {
|
|
let J1:! I;
|
|
}
|
|
|
|
interface K {
|
|
let K1:! J;
|
|
}
|
|
|
|
fn F(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I1 = (.K1.J1).I2) {}
|
|
|
|
// F's requirement I1 = I2 is not met, as I1 = () and I2 = {}
|
|
fn G(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I1 = () and .I2 = {}) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_self_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I & J & K where .(K.K1) = .Self as J and .(J.J1) = .Self as I and .(I.I1) = () and .(I.I2) = {}` into type implementing `I & J & K where .(K.K1) = .Self as J and .(J.J1) = .Self as I and .(I.I1) = .(I.I2)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_self_wrong_type.carbon:[[@LINE-7]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I1 = (.K1.J1).I2) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// F's requirement I1 = I2 is not met, as I1 = {} and I2 is unspecified
|
|
fn G2(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I1 = {}) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_self_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I & J & K where .(K.K1) = .Self as J and .(J.J1) = .Self as I and .(I.I1) = {}` into type implementing `I & J & K where .(K.K1) = .Self as J and .(J.J1) = .Self as I and .(I.I1) = .(I.I2)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_self_wrong_type.carbon:[[@LINE-19]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I1 = (.K1.J1).I2) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// F's requirement I1 = I2 is not met, as I2 = {} and I1 is unspecified
|
|
fn G3(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I2 = {}) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_self_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I & J & K where .(K.K1) = .Self as J and .(J.J1) = .Self as I and .(I.I2) = {}` into type implementing `I & J & K where .(K.K1) = .Self as J and .(J.J1) = .Self as I and .(I.I1) = .(I.I2)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_self_wrong_type.carbon:[[@LINE-31]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I & J & K where .K1 = .Self and .J1 = .Self and .I1 = (.K1.J1).I2) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- fail_todo_rewrite_requires_subst_in_nested_access_of_other.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let I1:! type;
|
|
}
|
|
|
|
interface J {
|
|
let J1:! I;
|
|
let J2:! type;
|
|
}
|
|
|
|
interface K {
|
|
let K1:! J;
|
|
}
|
|
|
|
// .K1.J1 is an ImplWitnessAccess into Self. The Self witness will be subst'd in
|
|
// for `U` and it will eval to the ImplWitnessAccess inside of `U.I1`. Then that
|
|
// will need to be subst'd to find the value of I1 in U's witness.
|
|
fn F(U:! I, T:! J & K where .J2 = (.K1.J1).I1) {}
|
|
|
|
fn G(U:! I where .I1 = (), T:! J & K where .K1 = .Self and .J1 = U and .J2 = ()) {
|
|
// CHECK:STDERR: fail_todo_rewrite_requires_subst_in_nested_access_of_other.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `J & K where .(J.J2) = () and .(K.K1) = .Self as J and .(J.J1) = U as I` into type implementing `J & K where .(J.J2) = .(K.K1).(J.J1).(I.I1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_todo_rewrite_requires_subst_in_nested_access_of_other.carbon:[[@LINE-6]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I, T:! J & K where .J2 = (.K1.J1).I1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// --- fail_rewrite_requires_subst_in_nested_access_of_other_wrong_type.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let I1:! type;
|
|
}
|
|
|
|
interface J {
|
|
let J1:! I;
|
|
let J2:! type;
|
|
}
|
|
|
|
interface K {
|
|
let K1:! J;
|
|
}
|
|
|
|
fn F(U:! I, T:! J & K where .J2 = (.K1.J1).I1) {}
|
|
|
|
// F's requirement J2 = I1 is not met as J2 = () and I1 = {}
|
|
fn G(U:! I where .I1 = {}, T:! J & K where .K1 = .Self and .J1 = U and .J2 = ()) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `J & K where .(J.J2) = () and .(K.K1) = .Self as J and .(J.J1) = U as I` into type implementing `J & K where .(J.J2) = .(K.K1).(J.J1).(I.I1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_wrong_type.carbon:[[@LINE-7]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I, T:! J & K where .J2 = (.K1.J1).I1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// F's requirement J2 = I1 is not met as J2 = () and I1 is unspecified
|
|
fn G2(U:! I, T:! J & K where .K1 = .Self and .J1 = U and .J2 = ()) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `J & K where .(J.J2) = () and .(K.K1) = .Self as J and .(J.J1) = U` into type implementing `J & K where .(J.J2) = .(K.K1).(J.J1).(I.I1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_wrong_type.carbon:[[@LINE-19]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I, T:! J & K where .J2 = (.K1.J1).I1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// F's requirement J2 = I1 is not met as I1 = {} and J2 is unspecified
|
|
fn G3(U:! I where .I1 = {}, T:! J & K where .K1 = .Self and .J1 = U) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `J & K where .(K.K1) = .Self as J and .(J.J1) = U as I` into type implementing `J & K where .(J.J2) = .(K.K1).(J.J1).(I.I1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_wrong_type.carbon:[[@LINE-31]]:13: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I, T:! J & K where .J2 = (.K1.J1).I1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// --- rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let I1:! type;
|
|
}
|
|
|
|
interface J {
|
|
let J1:! type;
|
|
}
|
|
|
|
interface K {
|
|
let K1:! J & I;
|
|
let K2:! type;
|
|
let K3:! type;
|
|
}
|
|
|
|
fn F(U:! I & J, T:! K where .K2 = .K1.I1 and .K3 = .K1.J1) {}
|
|
|
|
fn G(U:! I & J where .I1 = () and .J1 = {}, T:! K where .K1 = U and .K2 = () and .K3 = {}) {
|
|
F(U, T);
|
|
}
|
|
|
|
// --- fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let I1:! type;
|
|
}
|
|
|
|
interface J {
|
|
let J1:! type;
|
|
}
|
|
|
|
interface K {
|
|
let K1:! J & I;
|
|
let K2:! type;
|
|
let K3:! type;
|
|
}
|
|
|
|
fn F(U:! I & J, T:! K where .K2 = .K1.I1 and .K3 = .K1.J1) {}
|
|
|
|
// K2 = I1 fails since K2 = {} and I1 = ()
|
|
fn G(U:! I & J where .I1 = () and .J1 = {}, T:! K where .K1 = U and .K2 = {} and .K3 = {}) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `K where .(K.K2) = {} and .(K.K1) = U as I & J and .(K.K3) = {}` into type implementing `K where .(K.K2) = .(K.K1).(I.I1) and .(K.K3) = .(K.K1).(J.J1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE-7]]:17: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I & J, T:! K where .K2 = .K1.I1 and .K3 = .K1.J1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// K2 = I1 fails since I1 = () and K2 is unspecified.
|
|
fn G2(U:! I & J where .I1 = () and .J1 = {}, T:! K where .K1 = U and .K3 = {}) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `K where .(K.K1) = U as I & J and .(K.K3) = {}` into type implementing `K where .(K.K2) = .(K.K1).(I.I1) and .(K.K3) = .(K.K1).(J.J1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE-19]]:17: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I & J, T:! K where .K2 = .K1.I1 and .K3 = .K1.J1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// K2 = I1 fails since K2 = () and I1 is unspecified.
|
|
fn G3(U:! I & J where .J1 = {}, T:! K where .K1 = U and .K2 = () and .K3 = {}) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `K where .(K.K2) = () and .(K.K1) = U as I & J and .(K.K3) = {}` into type implementing `K where .(K.K2) = .(K.K1).(I.I1) and .(K.K3) = .(K.K1).(J.J1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE-31]]:17: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I & J, T:! K where .K2 = .K1.I1 and .K3 = .K1.J1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// K3 = J1 fails since J1 = {} and K3 is unspecified.
|
|
fn G4(U:! I & J where .I1 = () and .J1 = {}, T:! K where .K1 = U and .K2 = ()) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `K where .(K.K2) = () and .(K.K1) = U as I & J` into type implementing `K where .(K.K2) = .(K.K1).(I.I1) and .(K.K3) = .(K.K1).(J.J1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE-43]]:17: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I & J, T:! K where .K2 = .K1.I1 and .K3 = .K1.J1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// K3 = J1 fails since K3 = {} and J1 is unspecified.
|
|
fn G5(U:! I & J where .I1 = (), T:! K where .K1 = U and .K2 = () and .K3 = {}) {
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `K where .(K.K2) = () and .(K.K1) = U as I & J and .(K.K3) = {}` into type implementing `K where .(K.K2) = .(K.K1).(I.I1) and .(K.K3) = .(K.K1).(J.J1)` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(U, T);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR: fail_rewrite_requires_subst_in_nested_access_of_other_with_two_witnesses_wrong_type.carbon:[[@LINE-55]]:17: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(U:! I & J, T:! K where .K2 = .K1.I1 and .K3 = .K1.J1) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(U, T);
|
|
}
|
|
|
|
// --- fail_target_rewrites_dont_apply_to_source.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let I1:! type;
|
|
let I2:! type;
|
|
let I3:! type;
|
|
let I4:! type;
|
|
}
|
|
|
|
fn F(T:! I where .I1 = () and .I2 = ()) {}
|
|
|
|
fn G(T:! I where .I1 = .I2) {
|
|
// CHECK:STDERR: fail_target_rewrites_dont_apply_to_source.carbon:[[@LINE+7]]:3: error: cannot convert type `T` that implements `I where .(I.I1) = .(I.I2)` into type implementing `I where .(I.I1) = () and .(I.I2) = ()` [ConversionFailureFacetToFacet]
|
|
// CHECK:STDERR: F(T);
|
|
// CHECK:STDERR: ^~~~
|
|
// CHECK:STDERR: fail_target_rewrites_dont_apply_to_source.carbon:[[@LINE-6]]:6: note: initializing generic parameter `T` declared here [InitializingGenericParam]
|
|
// CHECK:STDERR: fn F(T:! I where .I1 = () and .I2 = ()) {}
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
F(T);
|
|
}
|
|
|
|
// --- nested_facet_type_used_as_root_facet_type.carbon
|
|
library "[[@TEST_NAME]]";
|
|
|
|
interface I {
|
|
let X:! type;
|
|
let Y:! type;
|
|
}
|
|
|
|
fn F(T:! I where .X = (I where .Y = {}), U:! T.X) {}
|
|
|
|
fn G(T:! I where .X = (I where .Y = {}), U:! I where .Y = {}) {
|
|
F(T, U);
|
|
}
|