Commit Graph

446 Commits

Author SHA1 Message Date
Nate Chandler
57bc67032d [SILOpt] Add tester for visit adjacent reborrows. 2022-10-11 17:30:42 -07:00
Nate Chandler
eee857320b [SILOpt] Add tester for CanonicalizeOSSALifetime. 2022-10-11 17:30:42 -07:00
Nate Chandler
82cd580145 [SILOptimizer] Add faux unit testing mechanism.
The testing works by way of a new pass "UnitTestRunner" and a new
instruction test_specification.  When a function contains
test_specification instructions, it invokes the UnitTest subclass named
in the test_specification instruction with the arguments specified in
that instruction.

For example, when running the unit-test-runner class, having the
instructions

```
test_specification "my-neato-utility 19 @function[callee].block[2] @trace[2]"
test_specification "my-neato-utility 43 @block @trace"
```

would result in the test associated with "my-neato-utility" in
UnitTestRunner.cpp being invoked twice.  Once with (19, aBlock, aValue),
and once with (43, anotherBlock, someOtherValue).  That UnitTest
subclass class would need to call takeUInt, takeBlock, and takeTrace on
the Arguments struct it is invoked with.  It would then pass those
arguments along to myNeatoUtility and dump out interesting results.  The
results would then be FileChecked.
2022-10-11 17:29:59 -07:00
Nate Chandler
ab35362056 [SIL] Added new test_specification instruction.
The new instruction exists only to be used in tests.  The idea is to
specify tests that ought to be run "in the context" of the containing
function.
2022-10-11 17:15:13 -07:00
Andrew Trick
11ef752a8a Add an OSSLifetimeAnalysis utility pass
Supports unit testing for OSSA lifetime utilities. These utilities are
the basis of maintaining valid OSSA form. They need to handle invalid
SIL (with incomplete OSSA lifetimes) because we rely on them to fixup
SIL after SILGen and after any transformation that may affect
ownership.
2022-10-04 13:27:47 -07:00
Josh Soref
730b16c569 Spelling siloptimizer
* access
* accessed
* accesses
* accessor
* acquiring
* across
* activated
* additive
* address
* addresses'
* aggregated
* analysis
* and
* appropriately
* archetype
* argument
* associated
* availability
* barriers
* because
* been
* beginning
* belongs
* beneficial
* blocks
* borrow
* builtin
* cannot
* canonical
* canonicalize
* clazz
* cleanup
* coalesceable
* coalesced
* comparisons
* completely
* component
* computed
* concrete
* conjunction
* conservatively
* constituent
* construct
* consuming
* containing
* covered
* creates
* critical
* dataflow
* declaration
* defined
* defining
* definition
* deinitialization
* deliberately
* dependencies
* dependent
* deserialized
* destroy
* deterministic
* deterministically
* devirtualizes
* diagnostic
* diagnostics
* differentiation
* disable
* discipline
* dominate
* dominates
* don't
* element
* eliminate
* eliminating
* elimination
* embedded
* encounter
* epilogue
* epsilon
* escape
* escaping
* essential
* evaluating
* evaluation
* evaluator
* executing
* existential
* existentials
* explicit
* expression
* extended
* extension
* extract
* for
* from
* function
* generic
* guarantee
* guaranteed
* happened
* heuristic
* however
* identifiable
* immediately
* implementation
* improper
* include
* infinite
* initialize
* initialized
* initializer
* inside
* instruction
* interference
* interferes
* interleaved
* internal
* intersection
* intractable
* intrinsic
* invalidates
* irreducible
* irrelevant
* language
* lifetime
* literal
* looks
* materialize
* meaning
* mergeable
* might
* mimics
* modification
* modifies
* multiple
* mutating
* necessarily
* necessary
* needsmultiplecopies
* nonetheless
* nothing
* occurred
* occurs
* optimization
* optimizing
* original
* outside
* overflow
* overlapping
* overridden
* owned
* ownership
* parallel
* parameter
* paths
* patterns
* pipeline
* plottable
* possible
* potentially
* practically
* preamble
* precede
* preceding
* predecessor
* preferable
* preparation
* probably
* projection
* properties
* property
* protocol
* reabstraction
* reachable
* recognized
* recursive
* recursively
* redundant
* reentrancy
* referenced
* registry
* reinitialization
* reload
* represent
* requires
* response
* responsible
* retrieving
* returned
* returning
* returns
* rewriting
* rewritten
* sample
* scenarios
* scope
* should
* sideeffects
* similar
* simplify
* simplifycfg
* somewhat
* spaghetti
* specialization
* specializations
* specialized
* specially
* statistically
* substitute
* substitution
* succeeds
* successful
* successfully
* successor
* superfluous
* surprisingly
* suspension
* swift
* targeted
* that
* that our
* the
* therefore
* this
* those
* threshold
* through
* transform
* transformation
* truncated
* ultimate
* unchecked
* uninitialized
* unlikely
* unmanaged
* unoptimized key
* updataflow
* usefulness
* utilities
* villain
* whenever
* writes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-10-03 18:31:33 -04:00
Nate Chandler
5d14610043 [SILOptimizer] Preserve arg attrs at cloning.
Arguments are copied into new cloned functions in a number of places.
Wherever that happens, be sure to transfer the attributes as well.
2022-09-26 16:55:50 -07:00
Hamish Knight
b12015c343 [SIL] Introduce the increment_profiler_counter instruction
This is a dedicated instruction for incrementing a
profiler counter, which lowers to the
`llvm.instrprof.increment` intrinsic. This
replaces the builtin instruction that was
previously used, and ensures that its arguments
are statically known. This ensures that SIL
optimization passes do not invalidate the
instruction, fixing some code coverage cases in
`-O`.

rdar://39146527
2022-09-07 17:55:13 +01:00
Michael Gottesman
5baf2af88a [sil] Add a new instruction called explicit_copy_addr.
This is exactly like copy_addr except that it is not viewed from the verifiers
perspective as an "invalid" copy of a move only value. It is intended to be used
in two contexts:

1. When the move checker emits a diagnostic since it could not eliminate a copy,
we still need to produce valid SIL without copy_addr on move only types since we
will hit canonical SIL eventually even if we don't actually codegen the SIL. The
pass can just convert said copy_addr to explicit_copy_addr and everyone is
happy.

2. To implement the explicit copy function for address only types.
2022-08-11 11:40:53 -07:00
Erik Eckstein
e8e61a9565 SIL: create cond_fail 1 instead of builtin "int_trap" for unconditional failures
`int_trap` doesn't provide a failure message, which makes crash reports hard to understand.
This is mostly the case for optimized casts which fail.

rdar://97681511
2022-07-28 16:05:07 +02:00
Michael Gottesman
1e6187c4f4 [sil] Update all usages of old API SILValue::getOwnershipKind() in favor of new ValueBase::getOwnershipKind().
Andy some time ago already created the new API but didn't go through and update
the old occurences. I did that in this PR and then deprecated the old API. The
tree is clean, so I could just remove it, but I decided to be nicer to
downstream people by deprecating it first.
2022-07-26 11:46:23 -07:00
Michael Gottesman
e1006c62f9 [move-only] Add copyable_to_moveonlywrapper and moveonlywrapper_to_copyable instructions.
These instructions have the following attributes:

1. copyably_to_moveonlywrapper takes in a 'T' and maps it to a '@moveOnly
T'. This is semantically used when initializing a new moveOnly binding from a
copyable value. It semantically destroys its input @owned value and returns a
brand new independent @owned @moveOnly value. It also is used to convert a
trivial copyable value with type 'Trivial' into an owned non-trivial value of
type '@moveOnly Trivial'. If one thinks of '@moveOnly' as a monad, this is how
one injects a copyable value into the move only space.

2. moveonlywrapper_to_copyable takes in a '@moveOnly T' and produces a new 'T'
value. This is a 'forwarding' instruction where at parse time, we only allow for
one to choose it to be [owned] or [guaranteed].

* moveonlywrapper_to_copyable [owned] is used to signal the end of lifetime of
the '@moveOnly' wrapper. SILGen inserts these when ever a move only value has
its ownership passed to a situation where a copyable value is needed. Since it
is consuming, we know that the no implicit copy checker will ensure that if we
need a copy for it, the program will emit a diagnostic.

* moveonlywrapper_to_copyable [guaranteed] is used to pass a @moveOnly T value
as a copyable guaranteed parameter with type 'T' to a function. In the case of
using no-implicit-copy checking this is always fine since no-implicit-copy is a
local pattern. This would be an error when performing no escape
checking. Importantly, this instruction also is where in the case of an
@moveOnly trivial type, we convert from the non-trivial representation to the
trivial representation.

Some important notes:

1. In a forthcoming commit, I am going to rebase the no implicit copy checker on
top of these instructions. By using '@moveOnly' in the type system, we can
ensure that later in the SIL pipeline, we can have optimizations easily ignore
the code.

2. Be aware of is that due to SILGen only emitting '@moveOnly T' along immediate
accesses to the variable and always converts to a copyable representation when
calling other code, we can simply eliminate from the IR all moveonly-ness from
the IR using a lowering pass (that I am going to upstream). In the evil scheme
we are accomplishing here, we perform lowering of trivial values right after
ownership lowering and before diagnostics to simplify the pipeline.

On another note, I also fixed a few things in SILParsing around getASTType() vs
getRawASTType().
2022-06-09 19:47:31 -07:00
Erik Eckstein
6b7ae416e6 SIL: remove unused instructions thin_function_to_pointer and pointer_to_thin_function 2022-03-25 15:44:59 +01:00
Andrew Trick
2fd4de411e [SIL-opaque] Removed [Unconditional]CheckedCastValue 2022-03-22 17:04:13 -07:00
Erik Eckstein
6a020f8f15 Stabilize and simplify SIL linkage and serialization
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.

As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
2022-03-09 15:28:05 +01:00
Michael Gottesman
68d37e142b [no-implicit-copy] Add a new instruction called MarkMustCheckInst and use it in the move checker.
This is an instruction that I am going to use to drive some of the ownership
based dataflow optimizations that I am writing now. The instruction contains a
kind that allows one to know what type of checking is required and allows the
need to add a bunch of independent instructions for independent checkers. Each
checker is responsible for removing all of its own mark instructions. NOTE:
MarkMustCheckInst is only allowed in Raw SIL since once we are in Canonical SIL
we want to ensure that all such checking has already occurred.
2022-01-29 14:49:39 -08:00
Erik Eckstein
383c52aa35 SIL: rename dealloc_ref [stack] -> dealloc_stack_ref
Introduce a new instruction `dealloc_stack_ref ` and remove the `stack` flag from `dealloc_ref`.

The `dealloc_ref [stack]` was confusing, because all it does is to mark the deallocation of the stack space for a stack promoted object.
2022-01-07 16:20:27 +01:00
Erik Eckstein
408cf02bc8 rework cross-module-optimization
* rename the CrossModuleSerializationSetup pass to simply CrossModuleOptimization
* remove the CMO specific serializer pass. Instead run the CrossModuleSerializationSetup pass directly before the standard serializer pass.
* correctly handle shared functions (e.g. specializations)
* refactoring
2021-12-20 11:33:02 +01:00
Pavel Yaskevich
4860f90fd7 [SIL] Add new flag to SILFunction - IsDistributed
Determines whether given SILFunction represents a distributed
method or its thunk.
2021-12-17 10:52:52 -08:00
Michael Gottesman
d74299e68d [move-function] Add a new instruction called mark_unresolved_move_addr.
This instruction is similar to a copy_addr except that it marks a move of an
address that has to be checked. In order to keep the memory lifetime verifier
happy, the semantics before the checker runs are the mark_unresolved_move_addr is
equivalent to copy_addr [init] (not copy_addr [take][init]).

The use of this instruction is that Mandatory Inlining converts builtin "move"
to a mark_unresolved_move_addr when inlining the function "_move" (the only
place said builtin is invoked).

This is then run through a special checker (that is later in this PR) that
either proves that the mark_unresolved_move_addr can actually be a move in which
case it converts it to copy_addr [take][init] or if it can not be a move, emit
an error and convert the instruction to a copy_addr [init]. After this is done
for all instructions, we loop back through again and emit an error on any
mark_unresolved_move_addr that were not processed earlier allowing for us to
know that we have completeness.

NOTE: The move kills checker for addresses is going to run after Mandatory
Inlining, but before predictable memory opts and friends.
2021-12-06 12:47:29 -08:00
Andrew Trick
90c0c8b60f Add rebind_memory SIL instruction.
Required for UnsafeRawPointer.withMemoryReboud(to:).

%out_token = rebind_memory %0 : $Builtin.RawPointer to %in_token

%0 must be of $Builtin.RawPointer type

%in_token represents a cached set of bound types from a prior memory state.

%out_token is an opaque $Builtin.Word representing the previously bound
types for this memory region.

This instruction's semantics are identical to ``bind_memory``, except
that the types to which memory will be bound, and the extent of the
memory region is unknown at compile time. Instead, the bound-types are
represented by a token that was produced by a prior memory binding
operation. ``%in_token`` must be the result of bind_memory or
2021-11-14 22:44:46 -08:00
Michael Gottesman
f9122a79b7 [moveOnly] Implement a new _copy function that performs an explicit copy value.
The key thing is that the move checker will not consider the explicit copy value
to be a copy_value that can be rewritten, ensuring that any uses of the result
of the explicit copy_value (consuming or other wise) are not checked.

Similar to the _move operator I recently introduced, this is a transparent
function so we can perform one level of specialization and thus at least be
generic over all concrete types.
2021-10-29 15:37:46 -07:00
Mishal Shah
c2fd49cebb Merge pull request #39473 from apple/rebranch
Update swift:main to support llvm-project:stable/20210726 changes (Rebranch merge)
2021-10-11 09:00:51 -07:00
Erik Eckstein
30a74f6284 SIL: remove the private_external SILLinkage
This was a relict from the -sil-serialize-all days. This linkage doesn't make any sense because a private function cannot be referenced from another module (or file, in case of non-wmo compilation).
2021-10-10 19:52:40 +02:00
Erik Eckstein
7849f09e52 SIL: remove the unused alloc_value_buffer, project_value_buffer and dealloc_value_buffer instructions.
Those instructions were use for the materializeForSet implementation, which was replaced by modify-coroutines.
2021-10-07 07:41:54 +02:00
swift-ci
d68dc5a975 Merge remote-tracking branch 'origin/main' into rebranch 2021-09-27 14:13:17 -07:00
Nate Chandler
4ff34aab31 [SIL] Enabled printing canonical module.
To print the module, use the new llvm flag -sil-print-canonical-module
which parallels the existing flag -sil-view-canonical-cfg.  When that
flag is passed, the new pass ModulePrinter is added to the diagnostic
pass pipeline after mandatory diagnostics have run.  The new pass just
prints the module to stdout.
2021-09-22 12:35:41 -07:00
swift-ci
f0def9afc0 Merge remote-tracking branch 'origin/main' into rebranch 2021-09-22 09:13:41 -07:00
Andrew Trick
e85228491d Rename AccessedStorage to AccessStorage
to be consistent with AccessPath and AccessBase.

Otherwise, the arbitrary name difference adds constant friction.
2021-09-21 23:18:24 -07:00
swift-ci
ebc9a3d560 Merge remote-tracking branch 'origin/main' into rebranch 2021-09-12 15:14:17 -07:00
Michael Gottesman
5590c7b526 [sil] Add a move_value instruction.
This is a new instruction that can be used by SILGen to perform a semantic move
in between two entities that are considered separate variables at the AST
level. I am going to use it to implement an experimental borrow checker.

This PR contains the following:

1. I define move_value, setup parsing, printing, serializing, deserializing,
   cloning, and filled in all of the visitors as appropriate.
2. I added createMoveValue and emitMoveValueOperation SILBuilder
   APIs. createMoveValue always creates a move and asserts is passed a trivial
   type. emitMoveValueOperation in contrast, will short circuit if passed a
   trivial value and just return the trivial value.
3. I added IRGen tests to show that we can push this through the entire system.

This is all just scaffolding for the instruction to live in SIL land and as of
this PR doesn't actually do anything.
2021-09-12 11:07:42 -07:00
swift-ci
ebad328a4f Merge remote-tracking branch 'origin/main' into rebranch 2021-09-01 09:14:57 -07:00
Min-Yih Hsu
343d842394 [SIL][DebugInfo] PATCH 3/3: Deprecate debug_value_addr SIL instruciton
This patch removes all references to DebugValueAddrInst class and
debug_value_addr instruction in textual SIL files.
2021-08-31 12:01:04 -07:00
swift-ci
2e11796710 Merge remote-tracking branch 'origin/main' into rebranch 2021-08-18 09:13:19 -07:00
Min-Yih Hsu
ffd1bcbd3b [SILOptimizer] Remove auxiliary debug scope when running SILDebugInfoGenerator
Previously inside SILDebugInfoGenerator (i.e. `-sil-based-debuginfo`
flag) we're removing all `debug_value` and `debug_value_addr` to avoid
mixing Swift and SIL source location. But we forgot to handle the source
location inside the auxiliary debug variable info in a `alloc_stack`
instruction. Which triggered a verification error regarding debug scope
mismatch.

This patch teaches SILDebugInfoGenerator to remove any auxiliary debug
variable scope, if there is any. Which might degrade the debug info
quality but we're mostly care about line number in this mode.

rdar://81709398
2021-08-17 15:30:28 -07:00
swift-ci
e0e2634b84 Merge remote-tracking branch 'origin/main' into rebranch 2021-07-06 09:35:07 -07:00
Min-Yih Hsu
d00a6cc0e3 [SIL][Frontend] Simplify debug info generation flow for SIL files
- If any of the `-g<kind>` flag is given -- except `-gnone`, debug
   info will be printed into every generated SIL files.
 - The `-gsil` is deprecated in favor of `-sil-based-debuginfo`. The
   SILDebugInfoGenerator Pass now generates intermediate SIL file with
   name "<output file>.sil_dbg_<n>.sil". Other functionalities of that
   Pass remain the same.
2021-06-30 17:21:58 -07:00
Evan Wilde
0aafd09835 F_None was renamed OF_None
This patch updates usages of F_None to OF_None, as LLVM changed that in
commit 3302af9d4c39642bebe64dd60a3aa162fefc44b2.
2021-06-23 10:36:39 -07:00
Erik Eckstein
d2fc6eb3b5 AliasAnalysis: make AliasAnalysis a function analysis and simplify the cache keys
Instead of caching alias results globally for the module, make AliasAnalysis a FunctionAnalysisBase which caches the alias results per function.
Why?
* So far the result caches could only grow. They were reset when they reached a certain size. This was not ideal. Now, they are invalidated whenever the function changes.
* It was not possible to actually invalidate an alias analysis result. This is required, for example in TempRValueOpt and TempLValueOpt (so far it was done manually with invalidateInstruction).
* Type based alias analysis results were also cached for the whole module, while it is actually dependent on the function, because it depends on the function's resilience expansion. This was a potential bug.

I also added a new PassManager API to directly get a function-base analysis:
    getAnalysis(SILFunction *f)

The second change of this commit is the removal of the instruction-index indirection for the cache keys. Now the cache keys directly work on instruction pointers instead of instruction indices. This reduces the number of hash table lookups for a cache lookup from 3 to 1.
This indirection was needed to avoid dangling instruction pointers in the cache keys. But this is not needed anymore, because of the new delayed instruction deletion mechanism.
2021-05-26 21:57:54 +02:00
Doug Gregor
e77a27e8ed [Concurrency] Introduce runtime detection of data races.
Through various means, it is possible for a synchronous actor-isolated
function to escape to another concurrency domain and be called from
outside the actor. The problem existed previously, but has become far
easier to trigger now that `@escaping` closures and local functions
can be actor-isolated.

Introduce runtime detection of such data races, where a synchronous
actor-isolated function ends up being called from the wrong executor.
Do this by emitting an executor check in actor-isolated synchronous
functions, where we query the executor in thread-local storage and
ensure that it is what we expect. If it isn't, the runtime complains.
The runtime's complaints can be controlled with the environment
variable `SWIFT_UNEXPECTED_EXECUTOR_LOG_LEVEL`:

  0 - disable checking
  1 - warn when a data race is detected
  2 - error and abort when a data race is detected

At an implementation level, this introduces a new concurrency runtime
entry point `_checkExpectedExecutor` that checks the given executor
(on which the function should always have been called) against the
executor on which is called (which is in thread-local storage). There
is a special carve-out here for `@MainActor` code, where we check
against the OS's notion of "main thread" as well, so that `@MainActor`
code can be called via (e.g.) the Dispatch library's
`DispatchQueue.main.async`.

The new SIL instruction `extract_executor` performs the lowering of an
actor down to its executor, which is implicit in the `hop_to_executor`
instruction. Extend the LowerHopToExecutor pass to perform said
lowering.
2021-04-12 15:19:51 -07:00
Slava Pestov
1e8ce52736 SIL: Strip [serialized] flag from functions even at -Onone
While the comment is correct to state that this won't enable any
new optimizations with -Onone, it does enable IRGen's lazy
function emission, which is important for 'reasync' functions,
which we don't want to emit at all even at -Onone.

This fixes debug stdlib builds with the new reasync versions
of the &&, || and ?? operators.
2021-04-08 01:47:27 -04:00
Erik Eckstein
8828d8e6bf tests: clean-up MemBehavior tests
Add more relevant instructions to dump in MemBehaviorDumper.
Therefore the -enable-mem-behavior-dump-all option can be removed.
Also mem-behavior-all.sil into mem-behavior.sil, because the sil-opt command lines don't differ anymore.
2021-03-24 11:19:00 +01:00
Erik Eckstein
542a378436 SIL: add FunctionRefInst::getReferencedFunction()
If we know that we have a FunctionRefInst (and not another variant of FunctionRefBaseInst), we know that getting the referenced function will not be null (in contrast to FunctionRefBaseInst::getReferencedFunctionOrNull).

NFC
2021-02-09 19:56:43 +01:00
Minhyuk Kim
e924cf6104 Replace usages of StringRef.find(Key) != StringRef::npos to StringRef.contains(Key) 2021-02-04 00:42:04 +09:00
Erik Eckstein
462e58d3cb SILLocation: a big refactoring and reducing its size from 3 to 2 words
My goal was to reduce the size of SILLocation. It now contains only of a storage union, which is basically a pointer and a bitfield containing the Kind, StorageKind and flags. By far, most locations are only single pointers to an AST node. For the few cases where more data needs to be stored, this data is allocated separately: with the SILModule's bump pointer allocator.

While working on this, I couldn't resist to do a major refactoring to simplify the code:

* removed unused stuff
* The term "DebugLoc" was used for 3 completely different things:
    - for `struct SILLocation::DebugLoc` -> renamed it to `FilePosition`
    - for `hasDebugLoc()`/`getDebugSourceLoc()` -> renamed it to `hasASTNodeForDebugging()`/`getSourceLocForDebugging()`
    - for `class SILDebugLocation` -> kept it as it is (though, `SILScopedLocation` would be a better name, IMO)
* made SILLocation more "functional", i.e. replaced some setters with corresponding constructors
* replaced the hand-written bitfield `KindData` with C bitfields
* updated and improved comments
2021-01-29 20:28:21 +01:00
Erik Eckstein
b7351780f7 SIL: move all the block-list modifying APIs to SILFunction.
... and remove SILFunction::getBlocks().

It's just a cleanup, NFC.
2021-01-14 17:35:31 +01:00
Meghana Gupta
81107e4235 Improve handling of copy_value and destroy_value in (#35011)
MemoryBehaviorVisitor

- Also, compute use points for destroy_value
- Cleanup explicit checks for refcount instructions in RLE
2020-12-14 22:44:58 -08:00
Michael Gottesman
a294ab61ad [ownership] Eliminate OperandOwnershipKindMap in favor of OwnershipConstraint.
I also used this as a moment to clarify the lattice that related
ValueOwnershipKind and OwnershipConstraint.
2020-11-10 19:07:30 -08:00
Ben Barham
7cee600bcd [SILGen] Add flag to skip typechecking and SIL gen for function bodies
Adds a new flag "-experimental-skip-all-function-bodies" that skips
typechecking and SIL generation for all function bodies (where
possible).

`didSet` functions are still typechecked and have SIL generated as their
body is checked for the `oldValue` parameter, but are not serialized.
Parsing will generally be skipped as well, but this isn't necessarily
the case since other flags (eg. "-verify-syntax-tree") may force delayed
parsing off.
2020-11-06 12:08:19 +10:00
Ben Barham
ea365d5d18 [TypeChecker] Do not attempt to skip typechecking for didSet
15f8eb45ea (see PR#26632) introduced
refined didSet semantics where the `oldValue` parameter is skipped if it
isn't used. This would perform typechecking, but later try to set the
body to skipped and thus fire an assert.

For now, do not attempt to skip typechecking of didSet accessors. Still
skip outputting their SIL though.
2020-11-05 11:27:38 +10:00