// 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 // // AUTOUPDATE package ExplorerTest api; interface A { let TA:! type; fn FA() -> TA; } interface B { let TB:! type; fn FB() -> TB; } class C(T:! type) { extend impl as A & B where .TA = i32 and .TB = i32 { fn FA() -> i32 { Print("(C(T) as A).FA()"); // OK, know that TA is i32 here. let v: Self.(A.TA) = 1; let w: i32 = v; return w; } fn FB() -> i32 { Print("(C(T) as B).FB()"); // OK, know that TB is i32 here. let v: Self.(B.TB) = 2; // Don't know that TA is i32; it could be specialized. // TODO: We should not accept this. let w: Self.(A.TA) = Self.(A.FA)(); return v + w; } } } impl C(i32) as A where .TA = (i32, i32) { fn FA() -> (i32, i32) { Print("(C(i32) as A).FA()"); return (6, 7); } } fn Main() -> i32 { Print("{0}", C(i32).(A.FA)()[0]); Print("{0}", C(i32).(A.FA)()[1]); // TODO: The implementation of C(T) as B eagerly picked the (non-final) // implementation of C(T) as A, so this ends up using a different // implementation of C(i32) as A than the one we just used, violating // coherence. Print("{0}", C(i32).(B.FB)()); return 0; } // CHECK:STDOUT: (C(i32) as A).FA() // CHECK:STDOUT: 6 // CHECK:STDOUT: (C(i32) as A).FA() // CHECK:STDOUT: 7 // CHECK:STDOUT: (C(T) as B).FB() // CHECK:STDOUT: (C(T) as A).FA() // CHECK:STDOUT: 3 // CHECK:STDOUT: result: 0