Commit Graph

1505 Commits

Author SHA1 Message Date
Slava Pestov
5197f38cda AST/Serialization: Some assertions for extensions
These helped me rule out my first theory about another bug, even
though it turned out to be unrelated.
2017-05-22 14:18:23 -07:00
Jordan Rose
e8229107ac [Serialization] Drop enums if a case payload can't be deserialized.
Layout for an enum depends very intimately on its cases---both their
existence and what their payload types are. That means there's no way
to "partly" recover from failure to deserialize an individual case's
payload type, the way we can partly recover from failing to
deserialize an initializer in a class. Add deserialization recovery
to enums by validating all of their payload types up front, and
dropping the enum if we can't import all of the cases.

This is the first time where we're trying to do deserialization
recovery for a /type/, and that could have many more ripple effects
than for a var/func/subscript/init. A better answer here might be to
still import the enum but mark it as unavailable, but in that case
we'd have to make sure to propagate that unavailability to anything
that /used/ the enum as well. (In Swift, availability is checked based
on use of the name, so if someone manages to refer to an enum using
inferred types we'd be in trouble.)

There is one case here that's not covered: if an enum case has a
payload that references a type declaration nested within the enum, but
then that nested type /itself/ can't be loaded for some reason, we
have no way to check that up front, because we can't even try to load
the nested type without loading its parent DeclContext (the enum). I
can't think of an easy solution for this right now.

(In the future, we'll be able to support dropping a single case for
resilient enums. But we're not there right now.)

rdar://problem/31920901
2017-05-17 17:05:15 -07:00
Jordan Rose
4a6fe941c7 [Serialization] Do less work checking if a value can be deserialized. (#9666)
Previously we recorded the canonical type of the declaration and made
sure we could deserialize that, but that's a lot of extra work
building up intermediate types that we mostly don't need. Instead,
record smaller types that represent the possible points of failure---
right now, just the nominal types that are referenced by the value
(function, variable/constant, subscript, or initializer). I chose to
use types instead of declarations here because types can potentially
encode more complicated constraints later (such as generic types
checking that their arguments still conform).

This gains us back 20% of type-checking time on a compile-time
microbenchmark: `let _ = [1, 2]`. I expect the effect is less dramatic
the more expressions you have, since we only need to deserialize
things once.
2017-05-17 09:02:45 -07:00
Slava Pestov
d0e4ba38b8 Serialization: Use nested type lookup table for cross-module references also
Fixes a class of deserialization issues in the merge-modules
step.

The setup was the following:

- File A defines a typealias A whose underlying type is a nested
  type S of a type T, defined in a different module.

- File B defines an extension of T, and the extension member's
  type references A.

When deserializing A, we would proceed to deserialize the
underlying type, which references T.S. This would first deserialize
T and perform a name lookup to find S, which would deserialize all
members, including pulling in extensions. Deserialization of the
extension defined in file B would then fail, because the declaration
for A is not yet available.

We had a previous fix for these problems in the single-module case;
a per-file lookup table mapping mangled nested type names to
declarations, allowing a nested type to be deserialized without
pulling in all members and extensions of its parent type.

This patch generalizes the nested type lookup table allowing it to
be used to resolve cross-module references as well. Also, we were
only writing out the nested type table when serializing a partial
swiftmodule corresponding to a source file. Removing this check
allows the nested type table to be serialized for modules built
with WMO enabled as well, such as the standard library.

Fixes <rdar://problem/30976604> and
<https://bugs.swift.org/browse/SR-4208>.
2017-05-16 19:06:26 -07:00
Doug Gregor
f5b99c75f4 [Serialization] Stop pre-loading generic environments.
Make generic environment deserialization lazy, which eliminates a
significant amount of up-front work. Most clients only need the
generic signature, not the full generic environment.
2017-05-16 11:06:17 -07:00
Joe Groff
119b3d198c Serialization: Handle possibly-null serialized xrefs for optional protocol witnesses.
Fixes SR-4850 | rdar://problem/32134722.
2017-05-12 18:57:35 -07:00
Jordan Rose
8a314d9440 Disallow subclassing when a class is missing vtable entries.
This isn't an inherent limitation of the language---in fact, it would
be a problem for library evolution if you had to know a superclass's
full vtable contents to generate the vtable for a subclass. However,
that's exactly where we are today, and that's not going to change for
Swift 4.

One small hole in the Swift 3 / Swift 4 story.

More rdar://problem/31878396
2017-05-10 17:03:32 -07:00
Jordan Rose
aeb0fedad1 Handle missing members in protocols as well.
This means both not crashing when we deserialize the protocol but
also emitting correct offsets for dynamic dispatch through the
protocol's witness table.

Also fix a bug with vtable and witness table slots for
materializeForSet accessors for properties that can't be
imported. Because materializeForSet doesn't have the type of the
property in its signature, it was taking a different failure path from
everything else, and that failure path didn't properly set the name or
flags for the missing member.

Finishes rdar://problem/31878396
2017-05-10 13:43:33 -06:00
Jordan Rose
4cdb597b23 Rename VTablePlaceholderDecl to MissingMemberDecl.
As such, we no longer insert two placeholders for initializers that
need two vtable slots; instead we record that in the
MissingMemberDecl. I can see MissingMemberDecl growing to be something
we'd actually show to users, that can be used for other kinds of
declarations that don't have vtable entries, but for now I'm not going
to worry about any of that.
2017-05-10 11:55:55 -06:00
Jordan Rose
47cddb1321 [Serialization] Generate VTablePlaceholder decls for classes.
They still aren't hooked up to anything yet, but now we can check that
they're showing up where we expect them.
2017-05-10 11:55:54 -06:00
Jordan Rose
d8eef2ea5e [Serialization] Record whether an initializer was newly 'required'
That is, whether an initializer is 'required', and either does not
override anything or overrides a non-required initializer. We don't
use this for anything now, but it'll show up in the next commit.
2017-05-10 11:55:54 -06:00
Joe Groff
e3e0f440a1 Serialization: Recovery for protocol conformances with changed witness or requirement signatures.
Deserializing a witness record in a conformance may fail if either of the requirement or witness changed name or type, most likely due to SDK modernization changes across Swift versions. When this happens, leave an opaque placeholder in the conformance to indicate that the witness exists but we don't get to see it. For expedience, right now this just witnesses the requirement to itself, so that code in the type checker or elsewhere that tries to ad-hoc devirtualize references to the requirement just gets the requirement back. Arguably, we shouldn't include the witness at all in imported conformances, since they should be an implementation detail, but that's a bigger, riskier change. This patch as is should be enough to address rdar://problem/31185053.
2017-05-09 09:15:04 -07:00
Jordan Rose
6c098033de Lift the decision of whether a method needs a vtable slot up to AST.
This lets us serialize that decision, which means we can conceivably
/change/ the decision in later versions of the compiler without
breaking existing code. More immediately, it's groundwork that will
eventually allow us to drop decls from the AST without affecting
vtable layout.

This isn't actually a great answer; what we really want is for SIL
vtables to be serialized consistently and treated as the point of
truth. But that would be more change than we're comfortable taking in
the Swift 4 timeframe.

First part of rdar://problem/31878396.
2017-05-04 17:49:47 -07:00
Doug Gregor
5bd609c98f Merge pull request #9156 from DougGregor/redundant-conformance-warnings
[Type checker] Downgrade some "redundant conformance" errors to warnings.
2017-05-01 15:00:14 -07:00
Doug Gregor
905b6b1710 [Serialization] Ignore parsed declarations when resolving x-refs.
A cross-reference in a module cannot refer to a parsed entity, because the parsed entity couldn’t have been seen when the module was built. Filter these out, which prevents a crash in the subsequent commit.
2017-05-01 13:20:25 -07:00
Bob Wilson
84d1630727 Merge pull request #9142 from shajrawi/loadable_by_addr_split
Code Size: Pass large loadable types by address instead of by value - Updated Version
2017-05-01 12:56:38 -07:00
Joe Shajrawi
d17258cac7 @in_constant calling convention - part of passing large loadable types by address 2017-04-30 10:13:02 -07:00
Graydon Hoare
cd48479d14 Merge pull request #9110 from graydon/grab-bag-of-metrics
Add an assortment of new "always-on" metrics.
2017-04-28 16:59:09 -07:00
Graydon Hoare
b5292f04f8 Add an assortment of new "always-on" metrics. 2017-04-28 13:56:13 -07:00
Jordan Rose
a9b6181ebd [Serialization] Drop support for serializing LValueType. (#9080)
This type never appears in API boundaries or in SIL instructions,
which means it never gets serialized.
2017-04-28 11:15:15 -07:00
Jordan Rose
db1fc95b69 [Serialization] Drop subscripts and initializers with problem types.
Finishes up the "big four" non-type decl kinds. Unfortunately,
indiscriminately dropping members from a class affects the layout
of its vtable. That issue is tracked by rdar://problem/31878396.
2017-04-27 18:30:34 -07:00
Jordan Rose
59a2545a7f [Serialization] Drop functions whose types can't be imported.
This doesn't handle generic functions with problems in their
requirements, but it's a step.
2017-04-27 18:30:34 -07:00
Jordan Rose
3ee8e843e7 [Serialization] Propagate errors through compound types.
If there's an error deserializing part of a type, just propagate it
out. Also add support for bound generic types. This isn't meant to be
full coverage of possible failures, just ones that are likely to come
up through the C/ObjC importer.

Still to do:
- Generic function types (only show up on functions)
- Unbound generic types (only show up on typealiases, which I may not
  even tackle)
2017-04-27 18:30:34 -07:00
Jordan Rose
1168cacf4f [Serialization] Drop decls whose types can't be deserialized.
Proof-of-concept for the above. This shouldn't be common---renames are
far more likely, and those we can track---but occurs when the
swift_wrapper attribute (the implementation of NS_STRING_ENUM) is
active in Swift 4 but not in Swift 3.

Note that this only checks the canonical interface type of the
declaration, because the non-canonical type may contain references to
the declaration's generic parameters.
2017-04-27 18:30:34 -07:00
Jordan Rose
10c62545c8 [Serialization] Extract error types to a separate header.
The next commits will need access from ModuleFile.cpp.

Also stop pretending we care what kind of error we got back, or that
we might get back random other errors that weren't accounted
for. That's good for crash logs, but not actually interesting here.
(Nearly every place that previously looked for OverrideError will
also accept the upcoming TypeError.)

No effective functionality change.
2017-04-27 18:30:33 -07:00
Jordan Rose
93963c58ed [Serialization] Look through unavailable compatibility aliases.
This keeps us from showing Swift 3 names in Swift 4 code;
unfortunately, as the test case shows, we still have a few cases where
Swift /4/ names will leak into Swift /3/ code. I'm considering this an
acceptable state of events for now.
2017-04-26 13:07:04 -07:00
Jordan Rose
abdaaefe29 [Serialization] Drop overriding initializers with missing bases.
This is the same as the last few commits, but with the additional
complication of designated initializers affecting other behavior
around the type. In particular, convenience initializers cannot be
invoked on subclasses if the designated initializers are not all
present on the subclass. If a designated initializer is dropped, it's
not possible to satisfy that.

It would be nice to do better here, since a class's initializers are
mostly independent of the superclass's initializers. Unfortunately, it
still affects whether /this/ class can inherit convenience
initializers, as well as vtable layout. This is conservative, at
least.
2017-04-24 11:53:54 -07:00
Jordan Rose
b76774f53d [Serialization] Sink readMembers into its only caller.
The next commit is going to want to look at the container whose
members are being loaded.
2017-04-24 11:53:54 -07:00
Jordan Rose
c170f07b85 [Serialization] Remove special case for magic "NS" prefix stripping. (#8916)
...which we no longer do.
2017-04-21 15:37:32 -07:00
Jordan Rose
f1902fd719 [Serialization] Drop typealiases whose underlying types have changed. (#8896)
In order to accomplish this, cross-module references to typealiases
are now banned except from within conformances and NameAliasTypes, the
latter of which records the canonical type to determine if the
typealias has changed. For conformances, we don't have a good way to
check if the typealias has changed without trying to map it into
context, but that's all right---the rest of the compiler can already
fall back to the canonical type.
2017-04-21 13:17:12 -07:00
Jordan Rose
13c950d7c2 [Serialization] Handle UnboundGenericTypes of generic typealiases.
Simple latent asserts-only bug. Thanks to Slava for the test case.
2017-04-21 09:31:05 -07:00
Slava Pestov
57b2c059db Serialization: Fix serialization of layout constraints 2017-04-19 00:52:14 -07:00
Slava Pestov
d49f8fb6d9 AST: Introduce primitive AnyObject type
Add a 'hasExplicitAnyObject()' bit to ProtocolCompositionType
to represent canonical composition types containing '& AnyObject'.

Serialize this bit and take it into account when building
ExistentialLayouts.

Rename ProtocolCompositionType::getProtocols() to getMembers()
since it can contain classes now, and update a few usages that
need further attention with FIXMEs or asserts.

For now, nothing actually constructs these types, and they will
trigger arounds asserts. Upcoming patches will introduce support
for this.
2017-04-13 21:17:05 -07:00
Jordan Rose
b5b4b3b3ce [Serialization] Tweak skipRecord helper to actually do checking. (#8761)
This is a step further from gracefully handling structural changes
to the module format, but we're nowhere near that anyway. At least
avoid the silly mistakes.
2017-04-13 17:25:37 -07:00
Jordan Rose
b93ee5fbec [Serialization] Don't bother with interface types for typealiases. (#8752)
These are fully recreatable from the underlying type, and indeed we
do that already. No intended functionality change.
2017-04-13 15:45:45 -07:00
Jordan Rose
d0a9ec509e [Serialization] Drop overriding properties with missing bases.
Like the previous commit, but with added trickiness because we also
serialize the form of the PatternBindingDecl a property came from.
Make getPattern handle a failure in the simple case that overrides
use, and pass that up to the PatternBindingDecl initialization. (This
can result in zero-element PatternBindingDecls, but that's fine.)

'getPattern' is also a change from 'maybeGetPattern', but every caller
knows how many patterns it expects, so accomodating the "maybe" case
is no longer important.
2017-04-11 10:37:30 -07:00
Jordan Rose
970f95930c [Serialization] Drop overriding subscripts with missing bases.
This only handles cases where a subscript disappears wholesale;
if one becomes read-only (for whatever terrible reason) the
compiler will still crash.
2017-04-11 10:37:30 -07:00
Jordan Rose
7e8d642e8e [Serialization] When crashing, note if mix-and-match may be to blame.
That is, a Swift 3 target imported into a Swift 4 context or vice
versa. This requires serializing the compatibility mode explicitly,
instead of including it in the textual version string that's only
for debugging.
2017-04-10 16:38:58 -07:00
Jordan Rose
2e8179d43a [Serialization] Fix comment. No functionality change.
Protocols can't have methods marked 'override'. Class contexts should
always be fine to drop a method that's an override (once the rest of
the world can handle it).
2017-04-10 13:57:48 -07:00
Jordan Rose
e7d1027e8a Merge pull request #8580 from jrose-apple/enable-experimental-deserialization-recovery
[Serialization] Proof-of-concept: drop overriding methods if the base is missing
2017-04-10 13:57:33 -07:00
Jordan Rose
73d4526943 [Serialization] Drop overriding methods if the base is missing.
Proof-of-concept for this sort of recovery. In the real world, it's
more likely that this will happen due to differences between Swift 3
and Swift 4, rather than changes in what macros are defined, but the
latter can still happen when debugging.

There's a lot to do here to consider this production-ready. There are
no generics involved and no potential circular references, and the
/rest/ of the compiler isn't prepared for this either. But it's cool
to see it working!

Actually recovering is hidden behind the new
-enable-experimental-deserialization-recovery option; without it the
compiler will continue to eagerly abort.
2017-04-05 18:32:08 -07:00
Jordan Rose
e831dca955 [Serialization] Save path traces from failed cross-references.
This is important information in a crash trace, so let's make sure to
preserve it even as the stack unwinds.
2017-04-05 16:40:56 -07:00
Jordan Rose
3dbc9de75b [Serialization] Use llvm::Expected for deserialization failures.
...but don't actually try to handle any of them yet. In fact, don't
even bother to /produce/ them yet, except for resolving
cross-references.
2017-04-05 15:17:01 -07:00
Doug Gregor
5c89eb84f0 [AST] Drop substitutions from type witnesses.
Nobody is using the actual substitutions, but we sure did a lot of
work to cope with them.
2017-04-05 11:21:38 -07:00
Doug Gregor
30ef37cb83 [AST] Eliminate "inherited conformances" from NormalProtocolConformance.
All of this information is recoverable from the more-general,
more-sane signature conformances, so stop
recording/serializing/deserializing all of this extra stuff.
2017-04-04 22:20:50 -07:00
Doug Gregor
71d5988ab3 [Serialization] Serialization for the @objc “Swift 3 inferred” bit 2017-03-31 21:22:15 -07:00
Jordan Rose
a8e4e72270 [Serialization] Delay all actions in the same module together. (#8123)
Back in December DougG added code to delay the formation of generic
environments until all declarations from a particular module had been
deserialized, to avoid circular dependencies caused by too-eager
deserialization of protocol members. This worked great for fully-built
modules, but still had some problems with module merging, the phase of
multi-file compilation where the "partial" swiftmodules that
correspond to each source file in a target are loaded and remitted as
a single swiftmodule. Fix this by picking one of the partial
swiftmodules as the representative one for delayed actions, and wait
until deserialization is complete for /all/ of the serialized ASTs in
the same target to form the generic environments.

rdar://problem/30984417
2017-03-16 15:22:06 -07:00
Huon Wilson
ca3a398b4a Merge pull request #8021 from huonw/protocol-where-clause
Parse/typecheck/print where clauses on protocols
2017-03-15 11:00:46 -07:00
Slava Pestov
18fbfd46c5 Serialization: Fix latent bug with extensions of nested generic types
ExtensionDecls for nested generic types have multiple generic parameter
lists, one for each level of nested generic context.

We only serialized the outermost list, though. This didn't cause any
problems as far as I can see because most of the time we seem to use
the GenericSignature instead, which has the correct generic parameters.

However since we still have usages of getGenericParamsOfContext() on
deserialized DeclContexts, better safe than sorry.

I added a test; the test used to pass on master, but with the new
assertion I added, it would fail without the other changes in this
patch.
2017-03-13 19:33:30 -07:00
Slava Pestov
0881877eaa Serialization: Remove code that became dead when PolymorphicFunctionType was removed 2017-03-13 19:33:16 -07:00