constrained_parameter.carbon 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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. // AUTOUPDATE
  6. // RUN: %{explorer-run}
  7. // RUN: %{explorer-run-trace}
  8. // CHECK:STDOUT: result: 0
  9. package ExplorerTest api;
  10. interface AddMul {
  11. fn Add[me: Self](o: Self) -> Self;
  12. fn Mul[me: Self](o: Self) -> Self;
  13. }
  14. external impl i32 as AddMul {
  15. fn Add[me: i32](o: i32) -> i32 {
  16. return me + o;
  17. }
  18. fn Mul[me: i32](o: i32) -> i32 {
  19. return me * o;
  20. }
  21. }
  22. class Holder(T:! AddMul) {
  23. var v: T;
  24. }
  25. interface Vector(Scalar:! AddMul) {
  26. fn Zero() -> Self;
  27. fn Add[me: Self](b: Self) -> Self;
  28. fn Scale[me: Self](v: Scalar) -> Self;
  29. fn Hold[me: Self](v: Scalar) -> Holder(Scalar);
  30. }
  31. class Point {
  32. var x: i32;
  33. var y: i32;
  34. impl Point as Vector(i32) {
  35. fn Zero() -> Point {
  36. return {.x = 0, .y = 0};
  37. }
  38. fn Add[me: Point](b: Point) -> Point {
  39. return {.x = me.x + b.x, .y = me.y + b.y};
  40. }
  41. fn Scale[me: Point](v: i32) -> Point {
  42. return {.x = me.x * v, .y = me.y * v};
  43. }
  44. fn Hold[me: Point](v: i32) -> Holder(i32) {
  45. return {.v = v};
  46. }
  47. }
  48. }
  49. fn AddAndScaleGeneric[T:! AddMul, U:! Vector(T)](a: U, s: T) -> U {
  50. return a.Add(U.Zero()).Scale(a.Hold(s).v);
  51. }
  52. fn Main() -> i32 {
  53. var a: Point = {.x = 2, .y = 1};
  54. var p: Point = AddAndScaleGeneric(a, 5);
  55. return p.x - 10;
  56. }