Introduce an `unsafe` expression akin to `try` and `await` that notes
that there are unsafe constructs in the expression to the right-hand
side. Extend the effects checker to also check for unsafety along with
throwing and async operations. This will result in diagnostics like
the following:
10 | func sum() -> Int {
11 | withUnsafeBufferPointer { buffer in
12 | let value = buffer[0]
| | `- note: reference to unsafe subscript 'subscript(_:)'
| |- warning: expression uses unsafe constructs but is not marked with 'unsafe'
| `- note: reference to parameter 'buffer' involves unsafe type 'UnsafeBufferPointer<Int>'
13 | tryWithP(X())
14 | return fastAdd(buffer.baseAddress, buffer.count)
These will come with a Fix-It that inserts `unsafe` into the proper
place. There's also a warning that appears when `unsafe` doesn't cover
any unsafe code, making it easier to clean up extraneous `unsafe`.
This approach requires that `@unsafe` be present on any declaration
that involves unsafe constructs within its signature. Outside of the
signature, the `unsafe` expression is used to identify unsafe code.
This attribute makes it so that a parameter of the annotated type, as well as
any type structurally containing that type as a field, becomes passed as
if `@_addressable` if the return value of the function has a dependency on
the parameter. This allows nonescapable values to take interior pointers into
such types.
Right now it is basically a version of nonisolated beyond a few simple cases
like constructors/destructors where we are pretty sure we want to not support
this.
This is part of my bringup strategy for changing nonisolated/unspecified to be
caller isolation inheriting.
Sema now type-checks the alternate ABI-providing decls inside of @abi attributes.
Making this work—particularly, making redeclaration checking work—required making name lookup aware of ABI decls. Name lookup now evaluates both API-providing and ABI-providing declarations. In most cases, it will filter ABI-only decls out unless a specific flag is passed, in which case it will filter API-only decls out instead. Calls that simply retrieve a list of declarations, like `IterableDeclContext::getMembers()` and friends, typically only return API-providing decls; you have to access the ABI-providing ones through those.
As part of that work, I have also added some basic compiler interfaces for working with the API-providing and ABI-providing variants. `ABIRole` encodes whether a declaration provides only API, only ABI, or both, and `ABIRoleInfo` combines that with a pointer to the counterpart providing the other role (for a declaration that provides both, that’ll just be a pointer to `this`).
Decl checking of behavior specific to @abi will come in a future commit.
Note that this probably doesn’t properly exercise some of the new code (ASTScope::lookupEnclosingABIAttributeScope(), for instance); I expect that to happen only once we can rename types using an @abi attribute, since that will create distinguishable behavior differences when resolving TypeReprs in other @abi attributes.
This attribute will allow you to specify an alternate version of the declaration used for mangling. It will allow minor adjustments to be made to declarations so long as they’re still compatible at the calling convention level, such as refining isolation or sendability, renaming without breaking ABI, etc.
The attribute is behind the experimental feature flag `ABIAttribute`.
Introduce an attribute to allow unsafe code within the annotated
declaration without presenting an unsafe interface to users. This is,
by its nature, and unsafe construct, and is used to document where
unsafe behavior is encapsulated in safe constructs.
There is an optional message that can be used as part of an audit
trail.
`UnsafeCastExpr` - A special kind of conversion that performs an unsafe
bitcast from one type to the other.
Note that this is an unsafe operation and type-checker is allowed to
use this only in a limited number of cases like: `any Sendable` -> `Any`
conversions in some positions, covariant conversions of function and
function result types.
Since the introduction of custom attributes (as part of property
wrappers), we've modeled the context of expressions within these
attributes as PatternBindingInitializers. These
PatternBindingInitializers would get wired in to the variable
declarations they apply to, establishing the appropriate declaration
context hierarchy. This worked because property wrappers only every
applied to---you guessed it!---properties, so the
PatternBindingInitializer would always get filled in.
When custom attributes were extended to apply to anything for the
purposes of macros, the use of PatternBindingInitializer became less
appropriate. Specifically, the binding declaration would never get
filled in (it's always NULL), so any place in the compiler that
accesses the binding might have to deal with it being NULL, which is a
new requirement. Few did, crashes ensued.
Rather than continue to play whack-a-mole with the abused
PatternBindingInitializer, introduce a new CustomAttributeInitializer
to model the context of custom attribute arguments. When the
attributes are assigned to a declaration that has a
PatternBindingInitializer, we reparent this new initializer to the
PatternBindingInitializer. This helps separate out the logic for
custom attributes vs. actual initializers.
Fixes https://github.com/swiftlang/swift/issues/76409 / rdar://136997841
Previously only some random decl attributes were included in the dump
with the source spelling (e.g. @objc), or some affected how the decl is
dumped. But the full attribute list has not been dumped. Dumping
attributes are useful for debugging attribute handling.
FunctionRefKind was originally designed to represent
the handling needed for argument labels on function
references, in which the unapplied and compound cases
are effectively the same. However it has since been
adopted in a bunch of other places where the
spelling of the function reference is entirely
orthogonal to the application level.
Split out the application level from the
"is compound" bit. Should be NFC. I've left some
FIXMEs for non-NFC changes that I'll address in a
follow-up.
This type is intended to be used to wrap compiler synthesized nodes
(i.e. variables) to make it easier for diagnostic to diagnose precise
failure locations.
Consider the situation like:
```
protocol P {}
extension Array: P where Element: P {}
func test<T: P>() -> T {
$_a = ...
$_b = ...
return [$_a, $_b]
}
```
This is a common pattern with result builders.
In this case if one of the elements don't conform to `P` the best
user experience would be to attach diagnostic to the element otherwise
the developers would have to figure out where in result expression
the error occured before attempting to fix it.
Attempting to dump opaque decl while type-checking a body of
the declaration it's associated with results in a request
cycle because underlying substitutions request would trigger
type-checking if the body isn't type-checked yet.
Today ParenType is used:
1. As the type of ParenExpr
2. As the payload type of an unlabeled single
associated value enum case (and the type of
ParenPattern).
3. As the type for an `(X)` TypeRepr
For 1, this leads to some odd behavior, e.g the
type of `(5.0 * 5).squareRoot()` is `(Double)`. For
2, we should be checking the arity of the enum case
constructor parameters and the presence of
ParenPattern respectively. Eventually we ought to
consider replacing Paren/TuplePattern with a
PatternList node, similar to ArgumentList.
3 is one case where it could be argued that there's
some utility in preserving the sugar of the type
that the user wrote. However it's really not clear
to me that this is particularly desirable since a
bunch of diagnostic logic is already stripping
ParenTypes. In cases where we care about how the
type was written in source, we really ought to be
consulting the TypeRepr.
`Builtin.FixedArray<let N: Int, T: ~Copyable & ~Escapable>` has the layout of `N` elements of type `T` laid out
sequentially in memory (with the tail padding of every element occupied by the array). This provides a primitive
on which the standard library `Vector` type can be built.
Instead of doing the pattern parsing in both the
C++ parser and ASTGen, factor out the parsing into
a request that returns the pattern to emit, regex
type, and version. This can then be lazily run
during type-checking.
@lifetime(target: source1, source2...) where target can be any
parameter or 'self'. We cannot have @lifetime attributes with duplicate targets.
Also, update the internal data structures. Previously LifetimeEntry stored
pairwise (target, source) dependencies. Now, LifetimeEntry will store an optional
target descriptor and an array of source descriptors.
Some requirement machine work
Rename requirement to Value
Rename more things to Value
Fix integer checking for requirement
some docs and parser changes
Minor fixes
Always add constraints, find fixes during simplify.
New separate fix for allow generic function specialization.
Improve parse heuristic for isGenericTypeDisambiguatingToken.
Degrade concrete type specialization fix to warning for macros.
There was a bunch of logic to lazily populate replacement types
corresponding to reducible generic parameters. This didn't seem
to have a clear purpose so let's remove it.
Out of an abundance of caution, we:
1. Left in parsing support for transferring but internally made it rely on the
internals of sending.
2. Added a warning to tell people that transferring was going to
be removed very soon.
Now that we have given people some time, remove support for parsing
transferring.
rdar://130253724