Files
swift-mirror/test/Constraints/result_builder_conjunction_selection.swift
Becca Royal-Gordon 8770c7f826 Rework ASTDumper (#68438)
This PR refactors the ASTDumper to make it more structured, less mistake-prone, and more amenable to future changes. For example:

```cpp
  // Before:
  void visitUnresolvedDotExpr(UnresolvedDotExpr *E) {
    printCommon(E, "unresolved_dot_expr")
      << " field '" << E->getName() << "'";
    PrintWithColorRAII(OS, ExprModifierColor)
      << " function_ref=" << getFunctionRefKindStr(E->getFunctionRefKind());
    if (E->getBase()) {
      OS << '\n';
      printRec(E->getBase());
    }
    PrintWithColorRAII(OS, ParenthesisColor) << ')';
  }

  // After:
  void visitUnresolvedDotExpr(UnresolvedDotExpr *E, StringRef label) {
    printCommon(E, "unresolved_dot_expr", label);

    printFieldQuoted(E->getName(), "field");
    printField(E->getFunctionRefKind(), "function_ref", ExprModifierColor);

    if (E->getBase()) {
      printRec(E->getBase());
    }

    printFoot();
  }
```

* Values are printed through calls to base class methods, rather than direct access to the underlying `raw_ostream`.
    * These methods tend to reduce the chances of bugs like missing/extra spaces or newlines, too much/too little indentation, etc.
    * More values are quoted, and unprintable/non-ASCII characters in quoted values are escaped before printing.
* Infrastructure to label child nodes now exists.
    * Some weird breaks from the normal "style", like `PatternBindingDecl`'s original and processed initializers, have been brought into line.
* Some types that previously used ad-hoc dumping functions, like conformances and substitution maps, are now structured similarly to the dumper classes.
* I've fixed the odd dumping bug along the way. For example, distributed actors were only marked `actor`, not `distributed actor`.

This PR doesn't change the overall style of AST dumps; they're still pseudo-S-expressions. But the logic that implements this style is now isolated into a relatively small base class, making it feasible to introduce e.g. JSON dumping in the future.
2023-09-11 23:56:38 -07:00

84 lines
2.5 KiB
Swift

// RUN: %target-typecheck-verify-swift -debug-constraints -disable-availability-checking 2>%t.err
// RUN: %FileCheck %s < %t.err
protocol P<Output> {
associatedtype Output
}
struct S<Output> : P {
init(_: Output) {}
}
@resultBuilder
struct Builder {
static func buildExpression<T>(_ e: T) -> T { e }
static func buildBlock<T1>(_ t1: T1) -> some P<T1> {
return S(t1)
}
static func buildBlock<T1, T2>(_ t1: T1, _ t2: T2) -> some P<(T1, T2)> {
return S((t1, t2))
}
static func buildBlock<T1, T2, T3>(_ t1: T1, _ t2: T2, _ t3: T3) -> some P<(T1, T2, T3)> {
return S((t1, t2, t3))
}
static func buildOptional<T>(_ value: T?) -> T? { return value }
}
do {
func test<T, U>(_: T, @Builder _: () -> some P<U>) {}
// CHECK: ---Initial constraints for the given expression---
// CHECK: (integer_literal_expr type="[[LITERAL_VAR:\$T[0-9]+]]" {{.*}}
// CHECK: (attempting type variable binding [[CLOSURE:\$T[0-9]+]] := () -> {{.*}}
// CHECK-NOT: (attempting type variable binding [[LITERAL_VAR]] := {{.*}}
// CHECK: (attempting conjunction element pattern binding element @ 0
// CHECK: (applying conjunction result to outer context
// CHECK: (attempting type variable binding [[LITERAL_VAR]] := Int
test(42) {
1
""
}
}
do {
func test<T, U>(_: T, @Builder _: (T) -> some P<U>) {}
// CHECK: ---Initial constraints for the given expression---
// CHECK: (integer_literal_expr type="[[LITERAL_VAR:\$T[0-9]+]]" {{.*}}
// CHECK: (attempting type variable binding [[LITERAL_VAR]] := Int
// CHECK: (attempting conjunction element pattern binding element @ 0
test(42) { v in
v
""
}
}
do {
func test<T: BinaryInteger, U>(@Builder _: (Bool) -> some P<T>, transform: (T?) -> U) {}
// CHECK: ---Initial constraints for the given expression---
// CHECK: (attempting type variable {{.*}} := () -> {{.*}}
// CHECK: (attempting conjunction element pattern binding element @ 0 :
// CHECK-NEXT: (pattern_named "x")
// CHECK: (attempting conjunction element syntactic element
// CHECK-NEXT: (call_expr {{.*}}
// CHECK: (attempting type variable {{.*}} := (Bool) -> {{.*}}
// CHECK: (attempting conjunction element pattern binding element @ 0
// CHECK: (pattern_named implicit "$__builder{{.*}}")
// CHECK: (applying conjunction result to outer context
// CHECK: (attempting type variable {{.*}} := (Int?) -> {{.*}}
// CHECK: (attempting disjunction choice {{.*}} bound to decl {{.*}}.Int.init(_:)
let _ = {
let x = 42
test { cond in
x
} transform: { v in
Int(v ?? 0)
}
}
}