|
| 1 | +// RUN: %empty-directory(%t) |
| 2 | + |
| 3 | +// RUN: %target-swift-frontend -emit-module %S/Inputs/lookup_moduleD.swift -module-name D -o %t -I %t |
| 4 | +// RUN: %target-swift-frontend -emit-module %S/Inputs/lookup_moduleC.swift -module-name C -o %t -I %t |
| 5 | +// RUN: %target-swift-frontend -emit-module %S/Inputs/lookup_moduleB.swift -module-name B -o %t -I %t |
| 6 | +// RUN: %target-swift-frontend -emit-module %S/Inputs/lookup_moduleA.swift -module-name A -o %t -I %t |
| 7 | +// RUN: %target-swift-frontend -emit-module %S/Inputs/lookup_module_exportsAC.swift -module-name ExportsAC -o %t -I %t |
| 8 | + |
| 9 | +// FIXME: Remove -verify-ignore-unknown. |
| 10 | +// RUN: %target-swift-frontend -typecheck -verify -verify-ignore-unknown -primary-file %s %S/Inputs/lookup_other.swift %S/Inputs/lookup_other2.swift %S/Inputs/lookup_other_compat.swift -I %t |
| 11 | + |
| 12 | +import ExportsAC |
| 13 | +import B |
| 14 | + |
| 15 | +infix operator ^^^ : DeclaredAcrossFiles |
| 16 | +func ^^^ (lhs: Int, rhs: Int) -> Int { 0 } |
| 17 | +func &&& (lhs: Int, rhs: Int) -> Int { 0 } |
| 18 | + |
| 19 | +// FIXME(SR-12132): The operator decl >>> is declared in module A, which we |
| 20 | +// should be able to see through ExportsAC. |
| 21 | +prefix func >>> (rhs: Double) {} // expected-error {{operator implementation without matching operator declaration}} |
| 22 | + |
| 23 | +// FIXME(SR-12132): We should also see precedencegroups in module A through |
| 24 | +// ExportsAC. |
| 25 | +infix operator ^^^^ : DeclaredInModuleA // expected-error {{unknown precedence group 'DeclaredInModuleA'}} |
| 26 | + |
| 27 | +// The operator decl for ??? is declared in both modules A and B, but has the |
| 28 | +// same default precedence group in both, so there's no ambiguity. |
| 29 | +func ??? (lhs: Int, rhs: Int) {} |
| 30 | + |
| 31 | +// Same for ???!, declared in modules ExportsAC and B, but has the same |
| 32 | +// precedence group in both. |
| 33 | +func ???! (lhs: Int, rhs: Int) {} |
| 34 | + |
| 35 | +// The operator decl for ???? is declared in both modules A and B, and has a |
| 36 | +// different precedence group in each. This should therefore be ambiguous. |
| 37 | +// However, for compatibility, we don't look through exports in other modules, |
| 38 | +// so we don't see the one in module A. |
| 39 | +func ???? (lhs: Int, rhs: Int) {} |
| 40 | + |
| 41 | +// The operator decl for ????! is declared in both modules ExportsAC and B, and |
| 42 | +// has a different precedence group in each. Therefore ambiguous. |
| 43 | +// FIXME: We shouldn't emit the unknown operator decl error. |
| 44 | +func ????! (lhs: Int, rhs: Int) {} // expected-error {{ambiguous operator declarations found for operator}} |
| 45 | +// expected-error@-1 {{operator implementation without matching operator declaration}} |
| 46 | + |
| 47 | +// Same as ????, the precedencegroup is declared in both modules A and B, but |
| 48 | +// we don't look into module A for compatibility. |
| 49 | +infix operator <?> : DeclaredInModulesAB |
| 50 | + |
| 51 | +// The precedencegroup is declared in both modules ExportsAC and B, therefore |
| 52 | +// ambiguous. |
| 53 | +// FIXME: We shouldn't emit the 'unknown precedence group' error. |
| 54 | +infix operator <!> : DeclaredInModulesBExportsAC // expected-error {{multiple precedence groups found}} |
| 55 | +// expected-error@-1 {{unknown precedence group 'DeclaredInModulesBExportsAC'}} |
| 56 | + |
| 57 | +// This precedencegroup is declared in this module as well as in both modules A |
| 58 | +// and B. The decl in this module should shadow the imported ones, but for |
| 59 | +// compatibility we don't see module A's decl and take module B's decl. |
| 60 | +infix operator <??> : DeclaredInModulesABShadowed |
| 61 | + |
| 62 | +// The operator decl for <? is declared in both modules A and B, but there's no |
| 63 | +// meaningful difference between the declarations, so legal. |
| 64 | +postfix func <? (lhs: Int) {} |
| 65 | + |
| 66 | +// Same thing, <! is declared in both modules ExportsAC and B, but there's no |
| 67 | +// meaningful difference between the declarations, so legal. |
| 68 | +postfix func <! (lhs: Int) {} |
| 69 | + |
| 70 | +// This precedencegroup is declared in both modules A and ExportsAC, but the |
| 71 | +// latter shadows the former. |
| 72 | +infix operator <???> : ShadowsModuleA |
| 73 | + |
| 74 | +// This precedencegroup is declared in modules A, C, and ExportsAC, but the |
| 75 | +// latter shadows both of the former. |
| 76 | +infix operator <????> : ShadowsModulesAC |
| 77 | + |
| 78 | +// This operator decl is declared in modules A, C, and ExportsAC, but the |
| 79 | +// latter shadows both of the former. |
| 80 | +func ????? (lhs: Int, rhs: Int) {} |
| 81 | + |
| 82 | +// This operator decl is declared in modules A, C, and ExportsAC, but the |
| 83 | +// latter shadows both of the former, despite them having different |
| 84 | +// precedencegroups. |
| 85 | +func ?????? (lhs: Int, rhs: Int) {} |
| 86 | + |
| 87 | +// FIXME: Module D is imported through exports in both lookup_other and |
| 88 | +// lookup_other2, but we fail to detect the fact that we're visiting the same |
| 89 | +// thing twice. |
| 90 | +infix operator <> : DeclaredInModuleD // expected-error {{unknown precedence group 'DeclaredInModuleD'}} |
| 91 | + |
| 92 | +// Also declared in lookup_other. To preserve compatibility, we allow an |
| 93 | +// unambiguous lookup that will favor this declaration over lookup_other. |
| 94 | +precedencegroup RedeclaredInModule {} |
| 95 | +infix operator *** : RedeclaredInModule // Okay. |
| 96 | + |
| 97 | +func testOperatorLookup() { |
| 98 | + // In lookup_other, DeclaredAcrossFiles is left associative, whereas in |
| 99 | + // module B it is non-associative. Make sure we use module B's for |
| 100 | + // compatibility. |
| 101 | + _ = 5 ^^^ 5 ^^^ 5 |
| 102 | + // expected-error@-1 {{adjacent operators are in unordered precedence groups 'AssignmentPrecedence' and 'DeclaredAcrossFiles'}} |
| 103 | + // expected-error@-2 {{adjacent operators are in non-associative precedence group 'DeclaredAcrossFiles'}} |
| 104 | + // expected-error@-3 {{cannot convert value of type '()' to expected argument type 'Int'}} |
| 105 | + |
| 106 | + // Same for &&&, in lookup_other it is declared as left associative. |
| 107 | + _ = 5 &&& 5 &&& 5 // expected-error {{adjacent operators are in non-associative precedence group 'DefaultPrecedence'}} |
| 108 | + |
| 109 | + // The operator >>> is declared in module A, which we should be able to see |
| 110 | + // through ExportsAC. |
| 111 | + >>>1 |
| 112 | + |
| 113 | + // We've been evil and overriden TernaryPrecedence in both modules A and B. |
| 114 | + // FIXME: We shouldn't emit the 'broken stdlib' error. |
| 115 | + true ? () : () // expected-error {{multiple precedence groups found}} |
| 116 | + // expected-error@-1 {{broken standard library: missing builtin precedence group 'TernaryPrecedence'}} |
| 117 | +} |
| 118 | + |
| 119 | +precedencegroup CastingPrecedence { |
| 120 | + lowerThan: AssignmentPrecedence |
| 121 | +} |
| 122 | + |
| 123 | +func testBuiltinPrecedenceGroupOverriding() { |
| 124 | + // Evil, but allowed. |
| 125 | + var x = 0 |
| 126 | + x = 0 as Int // expected-error {{cannot convert value of type '()' to type 'Int' in coercion}} |
| 127 | +} |
0 commit comments