Associate potential bindings with a constraint graph node and
start keeping track of added and removed constraints.
This is not a complete implementation because the ability to
infer bindings transitively is missing.
Binding inference requires constraint propagation through to referenced
type variables, in current "fixed bindings" storage mode it is impossible
to figure out whether tracked type variables are referenced by or from
a type variable.
Splitting storage for referenced by/from also helps to provide more
meaningful debug output and make sure there are no attempts to insert
duplicate references.
Currently the pattern is to collect the type variables and then unique
them. Instead of asking clients to do uniquing, let's just accept a set
as an argument.
Edge contraction was being performed for Bind, Equal,
BindToPointerType, and BindParam constraints. However, it's behavior
on everything but BindParam is the same as what matchTypes() already
does, so only look at BindParam constraints. This simplifies the code
but shouldn't change its behavior.
Since bindings now require finalization we need a new endpoint
which perform all of the required actions before returning complete
`PotentialBindings` object when they are requested for a particular
type variable without any other context.
Previously we would only gather one-way constraints
if they were found through a type variable in their
right hand side. However we would incorrectly check
this against the type variable that we started the
search at. This meant that if the constraint was
found through a fixed binding, we would never
return it, and could therefore fail to re-activate
it, leaving it unsolved.
Fix this issue by simply removing the check for
the RHS, and letting the constraint system handle
it instead.
Resolves rdar://64890308.
Holes couldn't be contracted instead solving of the constraint
has to be delayed until one of the sides is bound to a type,
otherwise there is a risk to loose contextual information.
The only caller was `contractEdges`, which would
only call it with constraints from either the
active or inactive list. The implementation can
therefore be replaced by
`ConstraintSystem::retireConstraint`, and
`removeGeneratedConstraint` can also be removed.
This simplifies fixing the master-next build. Upstream LLVM already
has a copy of this function, so on master-next we only need to delete
the Swift copy, reducing the potential for merge conflicts.
Start visiting transitive fixed bindings for type
variables, and stop visiting adjacencies for
`gatherConstraint`'s `AllMentions` mode.
This improves performance and fixes a correctness
issue with the old implementation where we could
fail to re-activate a coercion constraint, and
then let invalid code get past Sema, causing
either miscompiles or crashes later down the
pipeline.
Unfortunately this change requires us to
temporarily drop the non-ephemeral fix for a couple
of fairly obscure cases where the overload hasn't
yet been resolved. The logic was previously relying
on stale adjacency state in order to re-activate
the fix when the overload is bound, but it's not
connected on the constraint graph. We need to find
a way to connect constraints to unresolved
overloads they depend on.
Resolves SR-12369.
An awful pattern we use throughout the compiler is to save and restore global flags just for little things. In this case, it was just to turn on some extra options in AST printing for type variables. The kicker is that the ASTDumper doesn't even respect this flag. Add this as a PrintOption and remove the offending save-and-restores.
This doesn't quite get them all: we appear to have productized this pattern in the REPL.
By convention, most structs and classes in the Swift compiler include a `dump()` method which prints debugging information. This method is meant to be called only from the debugger, but this means they’re often unused and may be eliminated from optimized binaries. On the other hand, some parts of the compiler call `dump()` methods directly despite them being intended as a pure debugging aid. clang supports attributes which can be used to avoid these problems, but they’re used very inconsistently across the compiler.
This commit adds `SWIFT_DEBUG_DUMP` and `SWIFT_DEBUG_DUMPER(<name>(<params>))` macros to declare `dump()` methods with the appropriate set of attributes and adopts this macro throughout the frontend. It does not pervasively adopt this macro in SILGen, SILOptimizer, or IRGen; these components use `dump()` methods in a different way where they’re frequently called from debugging code. Nor does it adopt it in runtime components like swiftRuntime and swiftReflection, because I’m a bit worried about size.
Despite the large number of files and lines affected, this change is NFC.
This reinstates the use of direct adjacency information when gathering
constraints, effectively reverting
54bdd7b840.
Fixes the regression that commit caused, which is tracked by
rdar://problem/54274245.
Reinstate the list of adjacencies in each constraint graph node,
effectively reverting
dfdd352d3d. Exclude one-way constraints
from this computation; we'll handle them separately.
One-way constraint expressions, which are the only things that
introduce one-way constraints at this point, want to look through
lvalue types to produce values. Rename OneWayBind to OneWayEqual, map
it down to an Equal constraint when it is simplified (to drop
lvalue-ness), and apply that coercion during constraint application.
Part of rdar://problem/50150793.
There were a few places where we wanted fast testing to see whether a
particular type variable is currently of interest. Instead of building
local hash tables in those places, keep type variables in a SetVector
for efficient testing.
We only care about gathering a one-way constraint if (1) the left-hand
side is in the set of type variables we care about now, and (2) the
type variable we started from is in the right-hand side.
When we encounter a cycle in the one-way component graph due to constraints
that (e.g.) tie together the outputs of two one-way constraints, collapse
the components along the cycle into a single connected component, because
all of those type variables must be solved together.