@_preInverseGenerics(except: <inverses>) is an extension of the existing
@_preInverseGenerics attribute that provides selective control over which
inverse requirements are mangled into a declaration's symbol name.
While the bare @_preInverseGenerics strips all inverse constraints
(~Copyable and ~Escapable) from mangling, the 'except:' form allows specific
inverses to be retained. This is needed when a type like Span already had
~Copyable mangled into its ABI-stable symbols and now needs to retroactively
adopt ~Escapable without changing those existing symbols. You can now express
that with `@_preInverseGenerics(except: ~Copyable)` to strip-out every inverse
except ~Copyable to preserve the pre-existing ~Copyable-containing symbols.
It requires the new experimental feature `PreInverseGenericsExcept`.
rdar://176395527
borrow accessors can be supported in classes when they return 'let' properties, global 'let'.
Remove blanket restriction and add tests for supported cases
borrow accessors on enums are not supported in most common cases.
borrowing switch isn't available for Copyable types and SILGen work to support
borrow accessors with borrowing switch on ~Copyable types has not been done.
However, enums can support borrow accessors that return global let declarations.
Remove blanket restriction and add tests.
In some cases, it's useful to allow an availability macro to expand to an empty
availability specification list. Allow developers to express this using macros
that are defined to exactly the string `*`, while continuing to reject `*` in
availability macros that contain other entries.
Modify relevant portions of the type-checker and parser to allow, when the 'LiteralExpressions' experimental feature is enabled, for arbitrary integer-typed expressions in enum raw value specifiers. These expressions will be type-checked and constant-folded into an integer literal expression, keeping the current interface of 'EnumElementDecl' consistent for clients.
Previously, 'EnumRawValuesRequest' had two different "modes" which were discerned based on typechecking stage (structural | interface), where the former had the request compute all raw values, both user-specified literal expressions and computing increment-derived values as well; the latter would also type-check the user-specified expressions and compute their types.
- With the need to have enum case raw values support arbitrary integer expressions, the request ('EnumRawValuesRequest') has been refactored and simplified to *always* both compute all case raw values and perform type-checking of user-specified raw value expressions. This is done in order to allow the AST-based constant-folding infrastructure ('ConstantFoldExpression' request) to run on the expressions. Constant folding is invoked during the evaluation of 'EnumRawValuesRequest' on all user-specified raw value expressions, in order to be able to compute subsequent increment values and ensure the expressions are foldable. If they are not, i.e. if constant folding fails, a relevant diagnostic will be emitted.
- 'EnumElementDecl' continues to store the raw value expression, which is no longer a 'LiteralExpr' but rather an 'Expr'; however, the getter ('getRawValueExpr') continues to return a 'LiteralExpr' by invoking the constant-folding request on the stored value, which is guaranteed to return a cached result from a prior invocation in 'EnumRawValuesRequest', assuming it succeeded.
- Furthermore, the 'structural' request kind was previously not cached, whereas now because the request must always do the complete type-checking work, it is always cached.
Resolves rdar://168005520
Lifetime indices are never necessary in Swift, they unnecessarily expose
implementation details, and they make lifetime annotations more error-prone,
since they may need to be updated if a function's parameter list changes.
The Swift Syntax parser also cannot handle lifetime annotations where the target
is an index. The main reason the C++ parser supports them is because it is also
used for SIL.
To a function type's lifetimes, a base version of the type is first created with
no lifetime dependence info. This is then passed to the dependence checker, and
the resulting dependencies are added to it.
It would be possible to do this analysis by passing just the parameter list and
result type (which are available before the type is created), but this approach
lets us avoid dealing with a header inclusion cycle between Types.h, ExtInfo.h,
and LifetimeDependence.h, since it does not require AnyFunctionType::Param to be
defined in LifetimeDependence.h.
For now, we write `read`/`modify` to .swiftinterface files
so they can be read by the draft implementation in current
compilers. Here are some of the issues:
* We _cannot_ support `read`/`modify` in Swift sources without
the user specifying a flag. That's because the idiom below occurs
in real code, and would be broken by such support. So when
we enable the `CoroutineAccessors` flag by default, we _must_
not support `read`/`modify` as accessor notations in source.
```
struct XYZ {
// `read` method that takes a closure
func read(_ closure: () -> ()) { ... }
// getter that uses the above closure
var foo: Type {
read { ... closure ... }
}
}
```
* .swiftinterface files don't have the above problem.
Accessor bodies aren't stored at all by default, and
when inlineable, we always write explicit `get`.
So we can continue to accept `read`/`modify` notation
in interface files.
So our strategy here is:
* We'll accept both `read`/`modify` and `yielding borrow`/`yielding mutate`
in interface files for a lengthy transition period.
* We'll write `read`/`modify` to swiftinterface files for
a little longer, then switch to `yielding borrow`/`yielding mutate`.
* We'll disable `read`/`modify` support in source files
when we enable `CoroutineAccessors` by default.
(We can't even diagnose, due to the above idiom.)
This means that early adopters will have to update their sources
to use the new terminology. However, swiftinterface files
will be exchangeable between the new and old compilers for a little
while.
This implements two approaches for specifying derivatives of
yielding mutate and borrow accessors:
1. Using backticks to specify a yielding accessor:
```
// expected-note @+1 {{cannot register derivative for yielding borrow accessor}}
var computedProperty2: T {
yielding borrow { yield x }
yielding mutate { yield &x }
}
// expected-error @+1 {{referenced declaration 'computedProperty2' could not be resolved}}
@derivative(of: computedProperty2.`yielding borrow`)
mutating func vjpPropertyYieldingBorrow(_ newValue: T) -> (
value: (), pullback: (inout TangentVector) -> T.TangentVector
) { ... }
```
This requires it to be spelled with exactly one space.
2. Use .borrow or .mutate and resolve in Sema:
```
// expected-note @+1 {{cannot register derivative for yielding borrow accessor}}
var computedProperty2: T {
yielding borrow { yield x }
yielding mutate { yield &x }
}
// expected-error @+1 {{referenced declaration 'computedProperty2' could not be resolved}}
@derivative(of: computedProperty2.borrow)
mutating func vjpPropertyYieldingBorrow(_ newValue: T) -> (
value: (), pullback: (inout TangentVector) -> T.TangentVector
) { ... }
```
In order to support the latter, I've had to refactor the
resolution for these names so that error messages can show
the type (e.g., "yielding borrow") of the actual resolved
accessor, even if that's different from the specification.
This updates a large number of internal symbols, function names,
and types to match the final approved terminology. Matching the
surface language terminology and the compiler internals should
make the code easier for people to understand into the future.
This does not rename all the internal variables, functions, and types
whose names were based on the old syntax.
I think it adds new syntax support everywhere it's needed while
retaining enough of the old syntax support that early adopters will
see nice deprecation messages guiding them to the new syntax.
We don't have support for borrowing switch on Copyable types.
It is supported for ~Copyable types, but the return expression emission for borrow accessors is not yet implemented.
Diagnose instead of crashing the compiler.
Lexer should always set `Token.CommentLength` correctly because it
necessary for restoring to the token position with comments.
Otherwise, 'Token::isAtStartOfLine()' might not correctly set.
Implement the @export(implementation) and @export(interface) attributes
to replace @_alwaysEmitIntoClient and @_neverEmitIntoClient. Provide a
warning + Fix-It to start staging out the very-new
@_neverEmitIntoClient. We'll hold off on pushing folks toward
@_alwaysEmitIntoClient for a little longer.
Allow external declaration of global variables via `@_extern(c)`. Such
variables need to have types represented in C (of course), have only
storage (no accessors), and cannot have initializers. At the SIL
level, we use the SIL asmname attribute to get the appropriate C name.
While here, slightly shore up the `@_extern(c)` checking, which should
fix issue #70776 / rdar://153515764.
Currently, normal globals are represented as a PatternBindingDecl and a VarDecl in the AST, directly under the SourceFile:
```
// var variable_name = 42, compiled with -parse-as-library
(source_file ...
(pattern_binding_decl ...
(pattern_entry ...
(pattern_named ... "variable_name") ...
(var_decl "variable_name" ...
```
Top-level globals are represented more like local variables, under a TopLevelCodeDecl. Note that the VarDecl is still at the file scope. In SILGen, this case has some special handling to use the a storage of a global variable, and to avoid cleanups (see `emitInitializationForVarDecl`). Effectively, this means the globals are initialized inside the `main` function.
```
// var variable_name = 42, compiled without -parse-as-library
(source_file ...
(top_level_code_decl ...
(brace_stmt ...
(pattern_binding_decl ...
(pattern_named ... "variable_name") ...
(var_decl "variable_name" ... top_level_global
```
SE-0492 needs top-level globals that have a `@section` annotation to behave like a normal global -- initialization must happen statically, and not in `main`. This PR changes the parsing of those globals to match normal globals, without the TopLevelCodeDecl wrapper. SILGen and IRGen then handles them correctly.
Removes the underscored prefixes from the @_section and @_used attributes, making them public as @section and @used respectively. The SymbolLinkageMarkers experimental feature has been removed as these attributes are now part of the standard language. Implemented expression syntactic checking rules per SE-0492.
Major parts:
- Renamed @_section to @section and @_used to @used
- Removed the SymbolLinkageMarkers experimental feature
- Added parsing support for the old underscored names with deprecation warnings
- Updated all tests and examples to use the new attribute names
- Added syntactic validation for @section to align with SE-0492 (reusing the legality checker by @artemcm)
- Changed @DebugDescription macro to explicitly use a tuple type instead of type inferring it, to comply with the expression syntax rules
- Added a testcase for the various allowed and disallowed syntactic forms, `test/ConstValues/SectionSyntactic.swift`.
.swiftinterface sometimes prints a pattern binding initializer and the
accessor block. However the parser doesn't expect such constructs and
the disambiguation from trailing closures would be fragile. To make it
reliable, introduce a disambiguation marker `@_accessorBlock` .
`ASTPrinter` prints it right after `{` only if 1) The accessor block is
for a pattern binding declaration, 2) the decl has an initializer
printed, and 3) the non-observer accessor block is being printed. In the
parser, if the block after an initializer starts with
`{ @_accessorBlock`, it's always parsed as an accessor block instead of
a trailing closure.
rdar://140943107