symbolic_lookup.carbon 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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/convert.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/impl/lookup/symbolic_lookup.carbon
  10. // TIP: To dump output, run:
  11. // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/lookup/symbolic_lookup.carbon
  12. // --- self_type_facet_value_of_facet_access_type.carbon
  13. library "[[@TEST_NAME]]";
  14. interface X {}
  15. interface Y {}
  16. interface Z {}
  17. impl forall [T:! Y] T as X {}
  18. class C(T:! X) {}
  19. // The `adapt C(T)` line produces a symbolic impl lookup that `T` impls `X`:
  20. // - At first the impl lookup query in the eval block has self as
  21. // `BindSymbolicName(T:! Y)`.
  22. //
  23. // The call to construct `D` from in `Test()` makes a specific for `D`:
  24. // - The value of `T` in `D` is deduced to be a `FacetValue` of type `Y & Z`
  25. // pointing to the `BindSymbolicName(T:! Y & Z)` from `Test()`. But
  26. // `FacetValue` needs an instruction of type `TypeType` so the
  27. // `BindSymbolicName` is wrapped in `FacetAccessType`, meaning it's
  28. // `FacetValue(FacetAccessType(BindSymbolicName(T:! Y & Z)))`.
  29. // - That facet value is written to the specific of `D` constructed from
  30. // `Test()`.
  31. // - The eval block of `D` is run with the above specific. This runs the
  32. // symbolic impl lookup that `T` impls `X`. But with the `T` rewritten by the
  33. // specific to the `FacetValue(FacetAccessType(BindSymbolicName(T:! Y & Z)))`.
  34. //
  35. // The impl lookup unwraps the `FacetValue` to get the underlying type as it may
  36. // have access to a more constrained FacetType (with access to more interfaces)
  37. // than the `FacetValue` itself.
  38. //
  39. // In this case, the unwrap finds a `FacetAccessType`. Impl lookup must handle
  40. // the presence or absence of `FacetAccessType` in the query self type
  41. // consistently, while comparing the self type (after deduction) to the impl's
  42. // self type. This verifies we handle the case of the query not having a
  43. // `FacetAccessType` in the initial query that makes the symbolic lookup
  44. // instruction (`LookupImplWitness`), but then the self type being replaced
  45. // with a `FacetAccessType` when evaluating the instruction.
  46. class D(T:! Y) { adapt C(T); }
  47. fn Test(T:! Y & Z, d: D(T)) {}
  48. // --- final_symbolic_rewrite.carbon
  49. library "[[@TEST_NAME]]";
  50. interface Z(T:! type) {
  51. let X:! type;
  52. }
  53. // This impl has a rewrite to a symbolic value, and the `.Self` type has a
  54. // dependency on a generic parameter.
  55. final impl forall [T:! type, S:! type] T as Z(S) where .X = T {}
  56. class C {}
  57. fn F(T:! Z(C), t: T) {
  58. // This should typecheck, the `final impl` should give the same `T`.
  59. let a: T.X = t;
  60. }