Commit Graph

1590 Commits

Author SHA1 Message Date
John McCall
d7123c7e65 Merge pull request #64135 from rjmccall/variadic-generic-callee-results
Implement the callee side of returning a tuple containing a pack expansion
2023-03-06 11:11:47 -05:00
Richard Wei
833338f9ce [Macros] Top-level freestanding macros (#63553)
Allow freestanding macros to be used at top-level.
- Parse top-level `#…` as `MacroExpansionDecl` when we are not in scripting mode.
- Add macro expansion decls to the source lookup cache with name-driven lazy expansion. Not supporting arbitrary name yet.
- Experimental support for script mode and brace-level declaration macro expansions: When type-checking a `MacroExpansionExpr`, assign it a substitute `MacroExpansionDecl` if the macro reference resolves to a declaration macro. This doesn’t work quite fully yet and will be enabled in a future fix.
2023-03-06 07:15:20 -08:00
John McCall
157be3420c Implement the callee side of returning a tuple containing a pack expansion.
This required quite a bit of infrastructure for emitting this kind of
tuple expression, although I'm not going to claim they really work yet;
in particular, I know the RValue constructor is going to try to explode
them, which it really shouldn't.

It also doesn't include the caller side of returns, for which I'll need
to teach ResultPlan to do the new abstraction-pattern walk.  But that's
next.
2023-03-06 04:26:18 -05:00
Anthony Latsis
9bcddf4cb5 Merge pull request #63812 from AnthonyLatsis/keypath_setter_reasbtr
SILGen: Account for abstraction differences when assigning in key path setters
2023-03-03 23:53:34 +03:00
John McCall
06a7468e4f Implement the emission of pack expansion arguments in SILGen
Mostly fixing some existing code.
2023-03-03 02:52:32 -05:00
Andrew Trick
f1ff6958a3 Merge pull request #63825 from atrick/diagnose-implicit-raw-bitwise
Warn on implicit pointer conversion from nontrivial inout values.
2023-03-02 10:57:30 -08:00
Holly Borla
509188630b [ConstraintSystem] Implement type checking for converting a tuple to a
pack using the `.element` syntax.
2023-02-28 22:56:59 -08:00
Andrew Trick
bdeb58d61f Warn on implicit pointer conversion from nontrivial inout values.
Fixes a usability problem with implicit inout conversion to raw pointers.

For example, supporting this conversion turns out to be bad:

    void read_void(const void *input);

    func foo(data: inout Data) {
        read_void(&data)
    }

People understandably expect Foundation.Data to have the same sort of
implicit conversion as Array. But it does something very wrong
instead.

We could have added an an attribute to Data and other copy-on-write
containers to selectively suppress implicit conversion. But there is
no good reason to allow implicit conversion from any non-trivial
type. It is extremely dangerous, and almost always accidental. Note
that this problem becomes worse now that the compiler views imported
`char *` arguments as raw pointers. For example:

  void read_char(const char *input);

  var object: AnyObject = ...
  read_void(&object1)

This seems like a good time to correct this old Swift 3 behavior.

Plan: Add a warning now. Convert it to an error in Swift 6 language
mode based on feedback.

Fixes rdar://97963116 (It's really easy to accidentally corrupt a Data
object with the & operator)
2023-02-27 21:51:17 -08:00
John McCall
fb9578133b Steps towards supporting pack expansions properly in signature
lowering and argument emission.

Pack expansions in argument emission don't work yet, but I wanted
to land this bit of incremental progress.
2023-02-24 18:34:52 -05:00
Anthony Latsis
c2cd64ddff SILGen: Account for abstraction differences when assigning in key path setters 2023-02-22 05:28:00 +03:00
Adrian Prantl
5ff139dd6e Wire up mangled macro names in debug info.
rdar://104894694
2023-02-03 10:30:48 -08:00
Hamish Knight
a40f1abaff Introduce if/switch expressions
Introduce SingleValueStmtExpr, which allows the
embedding of a statement in an expression context.
This then allows us to parse and type-check `if`
and `switch` statements as expressions, gated
behind the `IfSwitchExpression` experimental
feature for now. In the future,
SingleValueStmtExpr could also be used for e.g
`do` expressions.

For now, only single expression branches are
supported for producing a value from an
`if`/`switch` expression, and each branch is
type-checked independently. A multi-statement
branch may only appear if it ends with a `throw`,
and it may not `break`, `continue`, or `return`.

The placement of `if`/`switch` expressions is also
currently limited by a syntactic use diagnostic.
Currently they're only allowed in bindings,
assignments, throws, and returns. But this could
be lifted in the future if desired.
2023-02-01 15:30:18 +00:00
Allan Shortlidge
80295fdaa1 SILGen: Avoid using back deployment thunks for high enough deployment targets.
If a function body references a declaration with the `@_backDeploy(before:)` attribute and that function body will only execute on deployment targets for which the ABI version of the decl is available then it is unnecessary to thunk the reference to the decl. Function bodies that may be emitted into other modules (e.g. `@inlinable`) must always use the thunk.

Resolves rdar://90729799
2023-01-25 17:22:23 -08:00
Adrian Prantl
6335f1dee5 Debug Info: Represent macro expansions as inlined functions.
This allows the debugger to choose whether to display the expanded macro
(inlined) or the original source code (parent frame).

rdar://102916513
2023-01-20 21:43:20 -08:00
Pavel Yaskevich
3fb69b3c3c [SIL] SILFunction: Add runtime accessible function attribute
This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
2022-12-20 09:33:44 -08:00
Holly Borla
d3bc4f52bc Merge pull request #62582 from hborla/pack-element-expr 2022-12-16 11:42:53 -05:00
Holly Borla
f1fd9acb23 [AST] Add 'PackElementExpr' for explicit pack elements spelled with the 'each'
keyword.
2022-12-14 20:45:51 -08:00
Nate Chandler
cd03615a1a [OpaqueValues] Initial key-path support.
Enough support for emitting key-paths SIL to build _Regex and
_StringProcessing.
2022-12-13 18:06:56 -08:00
Andrew Trick
f9861ec9c0 Add APIs for terminator results that forward ownership.
Add TermInst::forwardedOperand.

Add SILArgument::forwardedTerminatorResultOperand. This API will be
moved into a proper TerminatorResult abstraction.

Remove getSingleTerminatorOperand, which could be misused because it's
not necessarilly forwarding ownership.

Remove the isTransformationTerminator API, which is not useful or well
defined.

Rewrite several instances of complex logic to handle block arguments
with the simple terminator result API. This defines away potential
bugs where we don't detect casts that perform implicit conversion.

Replace uses of the SILPhiArgument type and code that explicitly
handle block arguments. Control flow is irrelevant in these
situations. SILPhiArgument needs to be deleted ASAP. Instead, use
simple APIs like SILArgument::isTerminatorResult(). Eventually this
will be replaced by a TerminatorResult type.
2022-12-12 12:37:35 -08:00
Erik Eckstein
ab1b343dad use new llvm::Optional API
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`

The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.

rdar://102362022
2022-11-21 19:44:24 +01:00
Michael Gottesman
427a5558f7 [move-only-address] When emitting a simple assignment, make sure to consume the move only type.
This was an oversight since I thought that `let _ = x` and `_ = x` were
codegened in the same way.

rdar://102491017
2022-11-17 16:25:11 -08:00
swift-ci
fd6fd76dae Merge pull request #42513 from jsoref/spelling-silgen
Spelling silgen
2022-11-09 23:28:43 -08:00
Josh Soref
9a6bf46c0f Spelling silgen
* actually
* arbitrary
* cargo-culted
* clazz
* constrained
* continuation
* coordinator
* coroutine
* derivative
* destroyer
* given
* have
* imported
* initialization
* items
* necessarily
* occurring
* omitting
* overridden
* parameter
* possible
* predecessor
* preparation
* resilience
* should
* struct
* that
* the
* throwing
* unexpectedly
* uniqueness
* using
* value
* villain

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-11-09 21:44:17 -05:00
Michael Gottesman
26db1f20a3 [move-only] Emit a copy_addr instead of a mark_unresolved_move_addr when applying the move operator to move only vars.
The reason why we are doing this is that we want move only addresses to be
checked by the move only address checker and not the move operator address
checker.

rdar://102056097
2022-11-07 14:29:03 -08:00
Allan Shortlidge
0d37f52fe0 APIDigester: Break cycle between Frontend and APIDigester targets.
Also push a utility that was previously on `SILDeclRef` down to AST so that the SIL dependency can be removed entirely from APIDigester.
2022-10-26 20:30:36 -07:00
Michael Gottesman
6cfa72d7aa Merge pull request #61651 from gottesmm/pr-727f8b30b3e32b1eb29003ac26642f5cf54b78e6
[silgen] Eliminate lifetime gap caused by AutoreleasingUnsafeMutablePointer's LValue component set.
2022-10-21 10:17:03 -07:00
Richard Wei
56e7cce809 [Macros] Parse MacroExpansionExpr and MacroExpansionDecl
Introduce `MacroExpansionExpr` and `MacroExpansionDecl` and plumb it through. Parse them in roughly the same way we parse `ObjectLiteralExpr`.

The syntax is gated under `-enable-experimental-feature Macros`.
2022-10-21 01:50:35 -07:00
Michael Gottesman
444c3ee5e0 [silgen] Eliminate lifetime gap caused by AutoreleasingUnsafeMutablePointer's LValue component set.
The problem here is that the AutoreleasingUnsafeMutablePointer's LValue
component would given the following Swift:

```
public class C {}

@inline(never)
func updateC(_ p: AutoreleasingUnsafeMutablePointer<C>) -> () {
  p.pointee = C()
}

public func test() -> C {
  var cVar = C()
  updateC(&cVar)
  return cVar
}
```

generate the following SIL as part of setting cVar after returning from updateC.

```
  %18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
  %19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
  %20 = load [trivial] %8 : $*@sil_unmanaged C    // user: %21
  %21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
  %22 = copy_value %21 : $C                       // user: %23
  assign %22 to %7 : $*C                          // id: %23
  end_access %7 : $*C                             // id: %24
```

Once we are in Canonical SIL, we get the following SIL:

```
  %18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
  %19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
  %20 = load [trivial] %8 : $*@sil_unmanaged C    // user: %21
  %21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
  %22 = copy_value %21 : $C                       // user: %23
  store %22 to [assign] %7 : $*C                          // id: %23
  end_access %7 : $*C                             // id: %24
```

which destroy hoisting then modifies by hoisting the destroy by the store assign
before the copy_value:

```
  %18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
  %19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
  destroy_addr %7 : $*C
  %20 = load [trivial] %8 : $*@sil_unmanaged C    // user: %21
  %21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
  %22 = copy_value %21 : $C                       // user: %23
  store %22 to [init] %7 : $*C                          // id: %23
  end_access %7 : $*C                             // id: %24
```

Given the appropriate Swift code, one could have that %21 is actually already
stored in %7 and has a ref count of 1. In such a case, the destroy_addr would
cause %21 to be deallocated before we can retain the value.

In order to fix this edge case as a bug fix, in the setter for
AutoreleasingUnsafeMutablePointer, we introduce a mark_dependence from the
copied value onto the memory. This ensures that destroy hoisting does not hoist
the destroy_addr past the mark_dependence, yielding correctness. That is we
generate the following SIL:

```
  %18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
  %19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
  %20 = load [trivial] %8 : $*@sil_unmanaged C    // user: %21
  %21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
  %22 = copy_value %21 : $C                       // user: %23
  %23 = mark_dependence %22 : $C on %7 : $*C
  assign %23 to %7 : $*C                          // id: %23
  end_access %7 : $*C                             // id: %24
```

For those unfamiliar, mark_dependence specifies that any destroy of the memory
in %7 can not move before any use of %23.

rdar://99402398
2022-10-20 16:55:17 -07:00
Slava Pestov
da8ae1d36d Sema: Remove PackExpr 2022-10-16 21:37:25 -04:00
Holly Borla
c4b946195e [AST] Replace the "type sequence" terminology with "parameter pack". 2022-10-10 16:28:13 -07:00
Holly Borla
67fb143f0e [AST] Remove ReifyPackExpr. 2022-10-10 16:25:26 -07:00
Holly Borla
19688cc2b1 [AST] Add the skeleton for PackExpansionExpr. 2022-10-07 20:13:18 -07:00
Hamish Knight
bca941b152 [AST] NFC: Rename IfExpr -> TernaryExpr
This matches what we call it in SwiftSyntax, and
is just generally clearer.
2022-09-28 10:33:31 +01:00
Joe Groff
cef7ecc122 Sema: Form all static member partial applications with one closure.
There was a special case here to type-check `T.init` as a single closure
`{ args.. in T.init(args..) }`, but really, we can do that for any static
member applied to a static metatype base, including operators.

Also fix SILGen's function conversion peephole so it looks through
`as (T...) -> U` coercions that don't involve bridging.
2022-09-26 14:19:56 -07:00
Joe Groff
f36668e3fa SILGen: Include more effects in function_conversion peephole.
Sometimes we emit a closure literal with escaping/nonthrowing/nonasync type
into a context that wants a nonescaping/throwing/async function, and it
ends up wrapped in a conversion. We can look through any of these and emit
the closure literal directly with those effects.
2022-09-22 17:00:00 -07:00
Joe Groff
d06f7b15d7 SILGen: Apply function_conversion peephole to CaptureListExprs.
Don't let a capture list suppress the reabstraction peephole when a closure
literal appears in a context with a function conversion.
2022-09-22 14:05:39 -07:00
Joe Groff
c6b6787f74 Sema: Simplify AST representation of key path literals as functions.
Previously, we would turn a key path literal like `\.foo` in function type
context into a double-wrapped closure like this:

```
  foo(\.x) // before type checking
  foo({ $kp$ in { $0[$kp$] } }(\.x)) // after type checking
```

in order to preserve the evaluation semantics of the key path literal. This
works but leads to some awkward raw SIL generated out of SILGen which misses
out on various SILGen peepholes and requires a fair number of passes to clean
up. The semantics can still be preserved with a single layer of closure, by
using a capture list:

```
  foo({[$kp$ = \.x] in $0[$kp$] }) // after type checking
```

which generates better natural code out of SILGen, and is also (IMO) easier
to understand on human inspection.

Changing the AST representation did lead to a change in code generation that
interfered with the efficacy of CapturePropagation of key path literals; for
key path literals used as nonescaping closures, a mark_dependence of the
nonescaping function value on the key path was left behind, leaving the key
path object alive. The dependence is severed by the specialization done in
the pass, so update the pass to eliminate the dependence.

Compared to the previous patch, this version removes the attempt to have
the type-checked function expression carry the noescape-ness of its context,
and allows for coerceToType to introduce a function conversion instead, since
that FunctionConversionExpr is apparently load-bearing for default argument
generators.
2022-09-22 12:00:22 -07:00
Erik Eckstein
97b2354be6 SIL: add needsStackProtection flags for address_to_pointer and index_addr instructions.
Also add new "unprotected" variants of the `addressof` builtins:
* `Builtin.unprotectedAddressOf`
* `Builtin.unprotectedAddressOfBorrow`
2022-09-08 08:42:22 +02:00
swift-ci
a66951aa3d Merge pull request #60521 from kavon/preconcurrency-var-access
Add missing function conversion for member access to preconcurrency vardecl.
2022-08-30 00:58:49 -07:00
Kavon Farvardin
6c24bc57cb [AST][SILGen] model ABI-safe casts of LValues
We needed a way to describe an ABI-safe cast of an address
representing an LValue to implement `@preconcurrency` and
its injection of casts during accesses of members.

This new AST node, `ABISafeConversionExpr` models what is
essentially an `unchecked_addr_cast` in SIL when accessing
the LVAlue.

As of now I simply implemented it and the verification of
the node for the concurrency needs to ensure that it's not
misused by accident. If it finds use outside of that,
feel free to update the verifier.
2022-08-29 20:58:26 -07:00
Slava Pestov
7a16b0275b AST: Allow one-element tuple types to be constructed
These will never appear in the source language, but can arise
after substitution when the original type is a tuple type with
a pack expansion type.

Two examples:
- original type: (Int, T...), substitution T := {}
- original type: (T...), substitution T := {Int}

We need to model these correctly to maintain invariants.

Callers that previously used to rely on TupleType::get()
returning a ParenType now explicitly check for the one-element
case instead.
2022-08-23 11:12:00 -04:00
Hamish Knight
64fcbd9412 [Profiler] Support lazy variable initializers
Start visiting LazyInitializerExpr for profiling,
such that we emit a profile counter when
initializing the initial value for the first time.

rdar://43393937
2022-08-19 14:03:40 +01:00
Meghana Gupta
196994fc11 Fix store_borrow generation in SILGen
This change ensures all store_borrows are ended with an end_borrow, and uses of the store_borrow
destination are all in the enclosing store_borrow scope and via the store_borrow return address.

Fix tests to reflect new store_borrow pattern
2022-08-16 15:08:22 -07:00
Slava Pestov
03f2225d96 Merge pull request #60463 from slavapestov/reduced-types
AST: Rename 'canonical wrt. generic signature' to 'reduced'
2022-08-09 16:12:58 -04:00
Slava Pestov
9d96ed940f AST: Rename 'canonical wrt. generic signature' to 'reduced'
We had two notions of canonical types, one is the structural property
where it doesn't contain sugared types, the other one where it does
not contain reducible type parameters with respect to a generic
signature.

Rename the second one to a 'reduced type'.
2022-08-09 12:46:31 -04:00
Michael Gottesman
6493886e1d [move-keyword] Wire up support for the move keyword in lvalue/rvalue emission.
I also updated the move function tests to show that this is working. As a nice
bonus, I was able to enable all of the tests also in a non-optimized stdlib.
2022-08-08 12:50:42 -07:00
Suyash Srijan
b2593ee5e3 [CSDiagnostics] Optional closure diagnostic improvement (#60321)
* [NFC] Add a getOptionalityDepth method to return the number of optionals a type has

* [NFC] Use getOptionalityDepth to remove existing code

* [AST] Add a new diagnostic note for suggesting optional chaining

* [CSDiagnostics] Tweak MissingOptionalUnwrapFailure to suggest using optional chaining on closure

* [Test] Add a couple of test cases for perform_optional_chain_on_closure

* [CSDiagnostics] Change DeclRefExpr casts to isa checks

* [AST] Update diagnostic phrasing

* [Sema] Use new diagnostic identifier and update comment

* [Test] Add a new test case for function type

* [Test] Update cfuncs_parse.swift tests to check for new diagnostic note
2022-08-04 21:40:17 +01:00
Hamish Knight
6e51841d14 [AST] Enforce that composeTuple drops parameter flags
Callers may either assert that the parameter flags
are empty, or ask for them to be dropped.
2022-08-02 13:56:31 +01:00
Slava Pestov
ce93261a86 Merge pull request #60310 from slavapestov/clean-up-override-substitutions
Clean up calculation of override substitutions
2022-07-30 20:05:00 -04:00
Slava Pestov
4538b1bb3e AST: Remove derivedSubs parameter from getOverrideSubstitutions()
We can apply a substitution map afterwards if needed.
2022-07-29 12:01:05 -04:00