|
| 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/min_prelude/facet_types.carbon |
| 6 | +// EXTRA-ARGS: --custom-core --no-dump-sem-ir |
| 7 | +// |
| 8 | +// AUTOUPDATE |
| 9 | +// TIP: To test this file alone, run: |
| 10 | +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/lookup/min_prelude/struct.carbon |
| 11 | +// TIP: To dump output, run: |
| 12 | +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/lookup/min_prelude/struct.carbon |
| 13 | + |
| 14 | +interface Z { |
| 15 | + let X:! type; |
| 16 | + fn ZZ() -> X; |
| 17 | +} |
| 18 | + |
| 19 | +class C { adapt (); } |
| 20 | +class D { adapt (); } |
| 21 | + |
| 22 | +impl {.a: (), .b: ()} as Z where .X = C { |
| 23 | + fn ZZ() -> C { return () as C; } |
| 24 | +} |
| 25 | + |
| 26 | +// A struct with different field names. Structs with different field names are |
| 27 | +// different types and can be matched by an impl lookup with matching field |
| 28 | +// names. |
| 29 | +impl {.aa: (), .bb: ()} as Z where .X = D { |
| 30 | + fn ZZ() -> D { return () as D; } |
| 31 | +} |
| 32 | + |
| 33 | +// TODO: Are structs with different field orders different types too, for impl |
| 34 | +// lookup? Or should this impl be diagnosed as overlapping with the impl on |
| 35 | +// `{.a, .b}`? Raised in: |
| 36 | +// https://github.com/carbon-language/carbon-lang/issues/5413 |
| 37 | +impl {.b: (), .a: ()} as Z where .X = D { |
| 38 | + fn ZZ() -> D { return () as D; } |
| 39 | +} |
| 40 | + |
| 41 | +fn F(T:! Z) -> T.X { |
| 42 | + return T.ZZ(); |
| 43 | +} |
| 44 | + |
| 45 | +fn G() { |
| 46 | + // Check which impl is selected for struct literals with different field |
| 47 | + // names. |
| 48 | + let c1: C = F({.a: (), .b: ()}); |
| 49 | + let d1: D = F({.aa: (), .bb: ()}); |
| 50 | + |
| 51 | + // TODO: It is unclear if `F` should return `C` or `D`, since it has the same |
| 52 | + // field names but different order as the impl that would give us `C` here. |
| 53 | + let d2: D = F({.b: (), .a: ()}); |
| 54 | +} |
0 commit comments