Commit Graph

1174 Commits

Author SHA1 Message Date
Robert Widmann
d2570cb964 Restore local type declarations list 2017-01-06 16:16:39 -07:00
Robert Widmann
0febbf0b72 Effectively revert #5778
This reverts the contents of #5778 and replaces it with a far simpler
implementation of condition resolution along with canImport.  When
combined with the optimizations in #6279 we get the best of both worlds
with a performance win and a simpler implementation.
2017-01-06 16:16:39 -07:00
Joe Groff
720f496b2e Merge pull request #6605 from jckarter/unsafe-bitcast-warnings
Sema: Warn about some common classes of `unsafeBitCast` misuse.
2017-01-06 09:13:56 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Joe Groff
d0787fb6b5 Sema: Warn about some common classes of unsafeBitCast misuse.
- Most immediately, we now have `withoutActuallyEscaping` as a supported way to temporarily reference a nonescaping closure as if it were escapable, and we plan to break the ABI for escaping and nonescaping closures so that the old `unsafeBitCast` workaround no longer works.
- `unsafeBitCast` is also commonly used to kludge pointers into different types, but we have more semantically meaningful APIs for type punning now. Guide users towards those APIs.
- Suggest more specific and type-safe operations, like `bitPattern:` initializers or `unsafeDowncast`, for the situations where `unsafeBitCast` is being used to avoid dynamic type checks or reinterpret numerical bits.
2017-01-05 21:19:02 -08:00
Robert Widmann
96f2a04f55 Merge pull request #6490 from modocache/ast
[SR-2757][Sema] Mark VarDecl in capture lists
2017-01-05 21:36:16 -07:00
Robert Widmann
dfa41d625b Optimize Condition Resolution (#6279)
* Pack the bits for IfConfigDecls into Decl

* Don't open symbols into a module when evaluating canImport statements

The module loaders now have API to check whether a given module can be
imported without importing the referenced module.  This provides a
significant speed boost to condition resolution and no longer
introduces symbols from the referenced module into the current context
without the user explicitly requesting it.

The definition of ‘canImport’ does not necessarily mean that a full
import without error is possible, merely that the path to the import is
visible to the compiler and the module is loadable in some form or
another.

Note that this means this check is insufficient to guarantee that you
are on one platform or another.  For those kinds of checks, use
‘os(OSNAME)’.
2017-01-05 12:08:54 -07:00
Slava Pestov
9db06ee36d Sema: Fixes for handling of 'Self'-returning methods
Protocol methods returning optionals, metatypes and functions
returning 'Self' are now handled correctly in Sema when
accessed with a base of existential type, eg:

protocol Clonable {
  func maybeClone() -> Self?
  func cloneMetatype() -> Self.Type
  func getClonerFunc() -> () -> Self
}

let c: Clonable = ...
let _: Clonable = c.maybeClone()
let _: Clonable.Type = c.cloneMetatype()

Previously, we were unable to model this properly, for
several reasons:

- When opening the function type, we replaced the return
  value in openedFullType _unconditionally_ with the
  existential type. This was broken if the return type
  was not the 'Self' parameter, but rather an optional,
  metatype or function type involving the 'Self' parameter.

- It was also broken because we lost information; if the
  return type originally contained an existential, we had
  no way to draw the distinction. The 'hasArchetypeSelf()'
  method was a hint that the original type contained a
  type parameter, but it was inaccurate in some subtle cases.

- Since we performed this replacement on both the
  'openedFullType' and 'openedType', CSApply had to "undo"
  it to replace the existential type with the opened
  existential archetype. This is because while the formal
  type of the access returns the existential type, in
  reality it returns the opened type, and CSApply has to
  insert the correct ErasureExpr.

  This was also done unconditionally, but even if it were
  done more carefully, it would do the wrong thing because
  of the 'loss of information' above.

- There was something fishy going on when we were dealing
  with a constructor that was declared on the Optional type
  itself, as seen in the fixed type_checker_crasher.

- TypeBase::eraseOpenedExistential() would transform a
  MetatypeType of an opened existential into a MetatypeType
  of an existential, rather than an ExistentialMetatypeType
  of the existential type.

The new logic has the following improvements:

- When opening a function type, we replace the 'Self' type
  parameter with the existential type in 'openedType', but
  *not* 'openedFullType'. This simplifies CSApply, since it
  doesn't have to "undo" this transformation when figuring
  out what coercions to perform.

- We now only use replaceCovariantResultType() when working
  with Self-returning methods on *classes*, which have more
  severe restrictions than protocols. For protocols, we walk
  the type using Type::transform() and handle all the cases
  properly.

- Not really related to the above, but there was a whole
  pile of dead code here concerning associated type references.

Note that SILGen still needs support for function conversions
involving an existential erasure; in the above Clonable example,
Sema now models this properly but SILGen still crashes:

let _: () -> Clonable = c.getClonerFunc()

Fixes <rdar://problem/28048391>, progress on <rdar://problem/21391055>.
2017-01-03 21:49:00 -08:00
Brian Gesiak
4108e1d9af [Sema] Mark VarDecl in capture lists
Fixes SR-2757.

Variables in capture lists are treated as 'let' constants, which can
result in misleading, incorrect diagnostics. Mark them as such in order
to produce better diagnostics, by adding an extra parameter to the
VarDecl initializer.

Alternatively, these variables could be marked as implicit, but that
results in other diagnostic problems: capture list variables that are
never used produce warnings, but these warnings aren't normally emitted for
implicit variables. Other assertions in the compiler also misfire when
these variables are treated as implicit.

Another alternative would be to walk up the AST and determine whether
the `VarDecl`, but there doesn't appear to be a way to do so.
2017-01-01 12:41:06 -05:00
Slava Pestov
4ed17f0f63 AST: Add a new 'isBeingValidated' flag to replace a couple of other flags
Previously, validateDecl() would check if the declaration had an
interface type and use that as an indication not to proceed.

However for functions we can only set an interface type after
checking the generic signature, so a recursive call to validateDecl()
on a function would "steal" the outer call and complete validation.

For generic types, this meant we could have a declaration with a
valid interface type but no generic signature.

Both cases were problematic, so narrow workarounds were put in
place with additional new flags. This made the code harder to
reason about.

This patch consolidates the flags and establishes new invariants:

- If validateDecl() returns and the declaration has no interface
  type and the isBeingValidated() flag is not set, it means one
  of the parent contexts is being validated by an outer recursive
  call.

- If validateDecl() returns and the declaration has the
  isBeingValidated() flag set, it may or may not have an interface
  type. In this case, the declaration itself is being validated
  by an outer recursive call.

- If validateDecl() returns and the declaration has an interface
  type and the isBeingValidated() flag is not set, it means the
  declaration and all of its parent contexts are fully validated
  and ready for use.

In general, we still want name lookup to find things that have an
interface type but are not in a valid generic context, so for this
reason nominal types and associated types get an interface type as
early as possible.

Most other code only wants to see fully formed decls, so a new
hasValidSignature() method returns true iff the interface type is
set and the isBeingValidated() flag is not set.

For example, while resolving a type, we can resolve an unqualified
reference to a nominal type without a valid signature. However, when
applying generic parameters, the hasValidSignature() flag is used
to ensure we error out instead of crashing if the generic signature
has not yet been formed.
2016-12-19 01:38:23 -08:00
Slava Pestov
fb0f372e94 AST: Move mapType{In,OutOf}Context() out of ArchetypeBuilder and clean up headers
- The DeclContext versions of these methods have equivalents
  on the DeclContext class; use them instead.

- The GenericEnvironment versions of these methods are now
  static methods on the GenericEnvironment class. Note that
  these are not made redundant by the instance methods on
  GenericEnvironment, since the static methods can also be
  called with a null GenericEnvironment, in which case they
  just assert that the type is fully concrete.

- Remove some unnecessary #includes of ArchetypeBuilder.h
  and GenericEnvironment.h. Now changes to these files
  result in a lot less recompilation.
2016-12-18 19:55:41 -08:00
practicalswift
16d6dce62e [gardening] Fix recently introduced typos. 2016-12-16 21:42:09 +01:00
Slava Pestov
2c6b9f71b6 AST: Change TypeAliasDecls to store an interface type as their underlying type
- TypeAliasDecl::getAliasType() is gone. Now, getDeclaredInterfaceType()
  always returns the NameAliasType.

- NameAliasTypes now always desugar to the underlying type as an
  interface type.

- The NameAliasType of a generic type alias no longer desugars to an
  UnboundGenericType; call TypeAliasDecl::getUnboundGenericType() if you
  want that.

- The "lazy mapTypeOutOfContext()" hack for deserialized TypeAliasDecls
  is gone.

- The process of constructing a synthesized TypeAliasDecl is much simpler
  now; instead of calling computeType(), setInterfaceType() and then
  setting the recursive properties in the right order, just call
  setUnderlyingType(), passing it either an interface type or a
  contextual type.

  In particular, many places weren't setting the recursive properties,
  such as the ClangImporter and deserialization. This meant that queries
  such as hasArchetype() or hasTypeParameter() would return incorrect
  results on NameAliasTypes, which caused various subtle problems.

- Finally, add some more tests for generic typealiases, most of which
  fail because they're still pretty broken.
2016-12-15 22:46:15 -08:00
Slava Pestov
757f253a3b AST: Remove the hack for lazily setting contextual types on VarDecls 2016-12-15 22:46:15 -08:00
Slava Pestov
a384b2a677 Don't call VarDecl::getType() on deserialized VarDecls 2016-12-15 22:46:15 -08:00
Robert Widmann
72beb9d80d Extract common code into StmtTransformer 2016-12-14 14:59:47 -05:00
Robert Widmann
a060eb5aca [SE-0075] Transfer the power of config resolution to Namebinding
This completely removes Parse’s ability to make any judgement calls
about compilation conditions, instead the parser-relevant parts of
‘evaluateConditionalCompilationExpr’ have been moved into
‘classifyConditionalCompilationExpr’ where they exist to make sure only
decls that we want to parse actually parse later.

The condition-evaluation parts have been moved into NameBinding in the
form of a Walker that evaluates and collapses IfConfigs.  This walker
is meant as an homage to PlaygroundLogger.  It should probably be
factored out into a common walker at some point in the future.
2016-12-14 14:59:47 -05:00
Doug Gregor
d86c4a8f42 [Serialization/AST] Lazy generic enviroments for extensions. 2016-12-12 21:33:30 -08:00
Doug Gregor
02ac9b593a [Serialization/AST] Lazily construct generic environments for generic types.
When deserializing the generic environment for a generic type, only
immediately deserialize the generic signature. The generic environment
will be deserialized later, when it's needed.
2016-12-12 20:53:17 -08:00
Doug Gregor
1739e14276 [Serialization/AST] Lazily construct generic environments for functions.
When we deserialize a function that has a generic environment, set the
generic signature and a key to allow lazy creation of the generic
environment. Because most clients won't need the generic environment,
this lets us avoid creating generic environments.
2016-12-12 20:53:17 -08:00
Doug Gregor
308fb88167 [AST] Fold lazy conformance loading into the LazyIterableDeclContextData.
This standardizes on just one side-lookup table for storing
information about lazy deserialization of nominal type and extension
declarations. NFC
2016-12-12 08:56:39 -08:00
Doug Gregor
8852937beb [AST] Optimize lazy-member storage for nominal type and extension declarations.
Save two pointers of storage in IterableDeclContext (a base class of
nominal type and extension declarations) by storing the lazy member
loader + context data in an ASTContext side table. It also makes it
easier to add more lazy context information later on.
2016-12-12 08:27:28 -08:00
Doug Gregor
5cb04f4635 [Serialization] Serialize a typealias' underlying type as an interface type.
We'll lazily map the interface type to a contextual type when requested.
2016-12-10 15:35:09 -08:00
Doug Gregor
67c2825bb0 [Serialization] Always set the “requires class” bit on deserialized protocols.
We were only setting the “requires class” bit when it was true. When it was false, semantic analysis would end up taking the slow path to compute the “false”, which is wasted effort.
2016-12-09 20:48:41 -08:00
Doug Gregor
1f89886ffa [Serialization] Stop serializing the contextual types of parameter declarations.
Only serialize the interface types of parameter declarations into the
module file, then lazily build the contextual types when
requested. This saves a small amount of space in the Swift module
files (~64k for the Swift standard library) and some effort on load.
2016-12-09 20:48:40 -08:00
Doug Gregor
c250acf8d9 [AST] Record the "owning" declaration context of generic environments.
While not strictly needed for type checking, it's extremely useful for
debugging and verification to know what context a particular generic
environment is associated with. This information was in a kludgy side
table, but it's worth a pointer in GenericEnvironment to always have
it available.
2016-12-07 21:35:53 -08:00
Slava Pestov
65088cc139 AST: Clean up usages of getDeclaredTypeInContext() and getExtensionType() 2016-12-04 21:15:02 -08:00
Slava Pestov
c1a216137c AST: Remove unnecessary field from ValueDecl
Now that getType() is gone, the pointer part of TypeAndAccess wasn't
used. Stick InterfaceTy there, saving a word of storage.
2016-12-04 00:24:47 -08:00
Slava Pestov
1a991da16d AST: Assign interface types to ParamDecls
First, ensure all ParamDecls that are synthesized from scratch are given
both a contextual type and an interface type.

For ParamDecls written in source, add a new recordParamType() method to
GenericTypeResolver. This calls setType() or setInterfaceType() as
appropriate.

Interestingly enough a handful of diagnostics in the test suite have
improved. I'm not sure why, but I'll take it.

The ParamDecl::createUnboundSelf() method is now only used in the parser,
and no longer sets the type of the self parameter to the unbound generic
type. This was wrong anyway, since the type was always being overwritten.
This allows us to remove DeclContext::getSelfTypeOfContext().

Also, ensure that FuncDecl::getBodyResultTypeLoc() always has an interface
type for synthesized declarations, eliminating a mapTypeOutOfContext()
call when computing the function interface type in configureInterfaceType().

Finally, clean up the logic for resolving the DynamicSelfType. We now
get the interface or contextual type of 'Self' via the resolver, instead
of always getting the contextual type and patching it up inside
configureInterfaceType().
2016-12-04 00:02:21 -08:00
Slava Pestov
9a4c740baf AST: Remove DeclContext::isProtocolSelf() 2016-12-02 12:21:55 -08:00
Slava Pestov
4ba00a0c06 AST: Remove FuncDecl::getDynamicSelf() and getDynamicSelfInterface() 2016-12-01 20:17:58 -08:00
Slava Pestov
b4d11338ec AST: Push ValueDecl::{has,get,set}Type() down to VarDecl
After recent changes, this asserts on all decls that are not VarDecls,
so we can just enforce that statically now. Interestingly, this turns
up some dead code which would have asserted immediately if called.

Also, replace AnyFunctionRef::getType() with
AnyFunctionRef::getInterfaceType(), since the old
AnyFunctionRef::getType() would just assert when called on
a Decl.
2016-12-01 19:28:13 -08:00
Slava Pestov
2ff9994313 Sema: Improve circularity checks
The previous patches regressed a test where we used to diagnose
(poorly) a circular associated type, like so:

  associatedtype e: e

With the error "inheritance from non-protocol, non-class type 'e'".

This error went away, because we end up not setting the interface
type of the associated type early enough. Instead, we return an
ErrorType from resolveTypeInContext() and diagnose nothing.

With this patch, emit a diagnostic at the point where the ErrorType
first appears.

Also, remove the isRecursive() bit from AssociatedTypeDecl, and
remove isBeingTypeChecked() which duplicates a bit with the same
name in Decl.
2016-12-01 13:00:19 -08:00
Slava Pestov
07780bd60c AST: Don't call hasType()/getType()/setType() on AbstractTypeParamDecls 2016-12-01 13:00:18 -08:00
Slava Pestov
2d83a79c2c AST: Remove TypeDecl::getDeclaredType()
A pointless use of polymorphism -- the result values are not
interchangeable in any practical sense:

- For GenericTypeParamDecls, this returned getDeclaredInterfaceType(),
  which is an interface type.

- For AssociatedTypeDecls, this returned the sugared AssociatedTypeType,
  which desugars to an archetype.

- For TypeAliasDecls, this returned TypeAliasDecl::getAliasType(),
  which desugars to a type containing archetypes.

- For NominalTypeDecls, this returned NominalTypeDecl::getDeclaredType(),
  which is the unbound generic type, a special case used for inferring
  generic arguments when they're not written in source.
2016-12-01 13:00:18 -08:00
Slava Pestov
8bdbe774e0 AST: Don't call hasType()/getType()/setType() on SubscriptDecls 2016-12-01 13:00:17 -08:00
Doug Gregor
589b469484 [AST] Extend a hack to work around broken circular inheritance checking.
Extending this hack recovers a regression in a previously-fixed
compiler crasher (#26725), and fixes two more compiler crashers. So,
despite it's utter lack of principle, it's progress.
2016-11-30 15:44:14 -08:00
Doug Gregor
79812aa073 [Archetype builder] (Almost) decouple PotentialArchetype from generic params.
The root potential archetypes in an archetype builder are associated
with generic parameters. Start decoupling potential archetypes from a
specific GenericTypeParamType and instead work with the abstracted
depth/index. The goal here is to allow the same archetype builder to
be used within different generic environments (which includes both
different generic parameters and different archetypes).

As part of this, boost the archetype builder's GenericTypeParamKey
from a local type to a more generic GenericParamKey that can be used
in other interfaces that want to work with abstracted generic
parameters.
2016-11-30 15:44:14 -08:00
Slava Pestov
c284bd409b AST: Assert if hasType() called on AbstractFunctionDecl or EnumElementDecl 2016-11-29 03:05:34 -07:00
Slava Pestov
0f7a455d7d AST: Don't call setType() on AbstractFunctionDecls and EnumElementDecls 2016-11-29 03:05:33 -07:00
Slava Pestov
8272fc1530 AST: Assert if getType() called on AbstractFunctionDecl or EnumElementDecl
These can contain PolymorphicFunctionTypes, and should no longer be
accessed.
2016-11-29 03:05:32 -07:00
Slava Pestov
40b0c5b3e1 AST: More accurate hasInterfaceType() 2016-11-29 03:05:30 -07:00
Slava Pestov
bd9e9d8600 AST: Refactor TypeDecl::getDeclaredInterfaceType() a bit 2016-11-29 03:05:24 -07:00
Slava Pestov
f803d8f12c AST: Remove AbstractFunctionDecl::getBodyResultType()
This is made redundant by the existing getResultInterfaceType()
accessor.
2016-11-29 03:05:23 -07:00
Slava Pestov
f6e692198c AST: Remove FuncDecl::getResultType() 2016-11-29 03:05:23 -07:00
Slava Pestov
55ad1800a1 AST: Remove ConstructorDecl::getArgumentType() 2016-11-29 03:05:23 -07:00
Slava Pestov
69e7cca64f AST: Remove ConstructorDecl::getResultType() 2016-11-29 03:05:22 -07:00
Slava Pestov
7d83704bd9 AST: Add ConstructorDecl::getArgumentInterfaceType() 2016-11-29 03:05:22 -07:00
Graydon Hoare
7c1dc18b64 Revert "Give all declarations an explicit interface type" 2016-11-24 09:55:27 -08:00
Slava Pestov
5b8524a9d1 AST: Remove FuncDecl::getResultType() 2016-11-24 02:35:35 -05:00