I believe this is because, after parsing and during AST construction, negative numeric literals have special treatment; the prefix -
is wiped away and the literal itself is flagged as negative, so there's no "operator" involved anymore during type checking:
$ echo '-5' | swiftc -dump-ast -
(source_file "<stdin>"
(top_level_code_decl range=[<stdin>:1:1 - line:1:2]
(brace_stmt implicit range=[<stdin>:1:1 - line:1:2]
(integer_literal_expr type='Int' location=<stdin>:1:1 range=[<stdin>:1:1 - line:1:2] negative value=5 builtin_initializer=Swift.(file).Int.init(_builtinIntegerLiteral:) initializer=**NULL**))))
With unary +
, on the other hand, the operator remains as an explicit invocation:
$ echo '+5' | swiftc -dump-ast -
(source_file "<stdin>"
(top_level_code_decl range=[<stdin>:1:1 - line:1:2]
(brace_stmt implicit range=[<stdin>:1:1 - line:1:2]
(prefix_unary_expr type='Int' location=<stdin>:1:1 range=[<stdin>:1:1 - line:1:2] nothrow
(dot_syntax_call_expr implicit type='(Int) -> Int' location=<stdin>:1:1 range=[<stdin>:1:1 - line:1:1] nothrow
(declref_expr type='(Int.Type) -> (Int) -> Int' location=<stdin>:1:1 range=[<stdin>:1:1 - line:1:1] decl=Swift.(file).AdditiveArithmetic extension.+ [with (substitution_map generic_signature=<Self where Self : AdditiveArithmetic> (substitution Self -> Int))] function_ref=single)
(argument_list implicit
(argument
(type_expr implicit type='Int.Type' location=<stdin>:1:1 range=[<stdin>:1:1 - line:1:1] typerepr='Int'))
))
(argument_list implicit
(argument
(integer_literal_expr type='Int' location=<stdin>:1:2 range=[<stdin>:1:2 - line:1:2] value=5 builtin_initializer=Swift.(file).Int.init(_builtinIntegerLiteral:) initializer=**NULL**))
)))))