Commit Graph

298 Commits

Author SHA1 Message Date
Slava Pestov
fe41900873 Sema: Split off ConstraintSystem::openUnboundGenericType() from openType()
The openType() function did two things:

- Replace unbound generic types like 'G' with fresh type variables
  applied to bound generic types, like 'G<$T0>'.

- Replace generic parameters with type variables from the replacement
  map.

The two behaviors were mutually exclusive and never used from the
same call site, so split them up into two independent functions.

Also, eliminate ConstraintSystem::openBindingType() since it was only
used in one place and could be expressed in terms of existing functions.
2017-05-23 02:10:03 -07:00
Slava Pestov
a6dfcd52cf Sema: Remove OverloadChoiceKind::TypeDecl, which was never used 2017-05-23 02:10:02 -07:00
Slava Pestov
ca6e4e6138 Sema: Clean up openGeneric() for nested generic types
If we had an unbound generic type whose parent was a bound
generic type, and the outer type's generic signature
placed generic constraints on outer parameters, we would
create type variables that weren't ever bound to anything.

Previously, this would never come up, but it will once
preCheckExpression() is folding more MemberRefExprs down
to TypeExprs.
2017-05-21 18:11:52 -07:00
Joe Groff
d16eb33477 Sema: Bind context generic params using the current ConstraintSystem's generic environment instead of the decl's DC.
Fixes SR-4833.
2017-05-19 10:47:57 -07:00
Slava Pestov
03ebba50be Sema: Fix lvalue access of class existential payloads
Now that SILGen can correctly lower lvalue accesses of
class existential payloads, remove a hack in Sema that
was simply doing the wrong thing.

Fixes <rdar://problem/31858378>.
2017-05-15 20:14:48 -07:00
Slava Pestov
6c443113ae Sema: Generic parameters can only bind to materializable types
I don't have a test case for this, so it might be a no-op.
But it's clearly "correct".
2017-05-10 22:01:15 -07:00
Graydon Hoare
b5292f04f8 Add an assortment of new "always-on" metrics. 2017-04-28 13:56:13 -07:00
Joe Groff
595e0e4ede Merge branch 'master' into keypaths 2017-04-19 18:38:24 -07:00
Slava Pestov
db58e02cb2 Sema: Hook up layout constraints to the solver
There were various problems with layout constraints either
being ignored or handled incorrectly. Now that I've exercised
this support with an upcoming patch, there are some fixes
here.

Also, introduce a new ExistentialLayout::getLayoutConstriant()
which returns a value for existentials which are class-constrained
but don't have a superclass or any class-constrained protocols;
an example would be AnyObject, or AnyObject & P for some
non-class protocol P.

NFC for now, since these layout-constrained existentials cannot
be constructed yet.
2017-04-13 21:17:05 -07:00
Slava Pestov
d58f049608 AST: Introduce ASTContext::getAnyObjectType()
This replaces a number of usages of KnownProtocolKind::AnyObject,
which is soon going away.
2017-04-13 21:17:05 -07:00
Slava Pestov
4efa9eaa8a Sema: Update getTypeOfMemberReference() for subclass existentials
If the member came from a class, we're not going to substitute
the 'Self' type. Instead, we open the existential, upcast the
archetype up to the class type and access the member as if it
were a class member in the usual way.
2017-04-10 17:05:44 -07:00
Slava Pestov
819dfd5211 Sema: Better type safety for opened types map
Now that we no longer map dependent member types to fresh type
variables, the keys in the replacement map can just be
GenericTypeParamTypes.
2017-04-10 17:04:36 -07:00
Slava Pestov
ed4c681aae Sema: Simplify Solution::computeSubstitutions()
Don't pass in the opened type; instead have the caller call
simplifyType() if needed. Also, make computeSubstitutions()
bail out if there's no generic signature, which allowed
unifying several generic vs non-generic code paths.

Hopefully there is enough short circuiting in there now that
we're not doing any extra work in the non-generic case.
2017-04-10 17:04:36 -07:00
Slava Pestov
6b4c877b68 Sema: simplifyType() can return early if the type has no variables
This allows calling simplifyType() unconditionally even if we
know we don't have any type variables in the type.
2017-04-10 17:04:36 -07:00
Joe Groff
964dc0e174 Sema: (wip) Overload resolution for keypath subscripts.
TODO: Some diagnostic regressions:
test-macosx-x86_64/Compatibility/tuple_arguments.swift
test-macosx-x86_64/Constraints/diagnostics.swift
test-macosx-x86_64/Constraints/tuple_arguments.swift
test-macosx-x86_64/expr/unary/keypath/keypath.swift
test-macosx-x86_64/expr/unary/selector/selector.swift
2017-04-09 16:38:02 -07:00
Xi Ge
75e191f5ac AST: Summarize a commonly used call chain in AbstractFunctionDecl. NFC (#8424) 2017-03-30 10:51:10 -07:00
Joe Groff
eb40d4303b Sema: Add a stdlib-internal _openExistential helper.
Leverage the "special type-checking semantics" hack to pass an opened existential down to an arbitrary subexpression. Please don't use this.
2017-03-10 13:41:00 -08:00
Mark Lacey
b026a07fd8 Add a scale-test counter for expression type checking.
Also add the first example of using the counter to test for
known-exponential typechecking behavior for nil-coalescing.
2017-02-23 12:08:30 -08:00
Slava Pestov
1a8ba93e59 Sema: Refactor getTypeOfMemberReference() for generic subscripts
Subscripts in generic context will soon have a
GenericFunctionType, so get ready to handle that.
2017-02-21 23:52:12 -08:00
Hugh Bellamy
f001b7562b Use relatively new LLVM_FALLLTHROUGH instead of our own SWIFT_FALLTHROUGH 2017-02-12 10:47:03 +07:00
swift-ci
014abc3b4f Merge pull request #7088 from graydon/rdar-29684330-count-constraint-solving-memory-more-precisely 2017-02-06 14:55:55 -08:00
Graydon Hoare
9cb1c52fd8 Count constraint-solving memory more precisely, rdar://29684330 2017-02-06 13:04:19 -08:00
Slava Pestov
cf4043b668 AST: Get rid of old form of Type::subst()
First, add some new utility methods to create SubstitutionMaps:

- GenericSignature::getSubstitutionMap() -- provides a new
  way to directly build a SubstitutionMap. It takes a
  TypeSubstitutionFn and LookupConformanceFn. This is
  equivalent to first calling getSubstitutions() with the two
  functions to create an ArrayRef<Substitution>, followed by
  the old form of getSubstitutionMap() on the result.

- TypeBase::getContextSubstitutionMap() -- replacement for
  getContextSubstitutions(), returning a SubstitutionMap.

- TypeBase::getMemberSubstitutionMap() -- replacement for
  getMemberSubstitutions(), returning a SubstitutionMap.

With these in place, almost all existing uses of subst() taking
a ModuleDecl can now use the new form taking a SubstitutionMap
instead. The few remaining cases are explicitly written to use a
TypeSubstitutionFn and LookupConformanceFn.
2017-02-03 19:55:40 -08:00
Mark Lacey
ecedb337e7 [Sema] In simplifyType, if substitution fails retry with IUOs stripped.
We can end up with IUOs bound as a result of overload resolution. When
this happens and the resulting type is used as a generic, we can end up
with dependent member types that fail to simplify properly as a result
of failing to substitute due to the IUO getting in the way. In these
cases it should be completely safe to strip the IUO off and retry
substitution with the base type.

This isn't really an ideal fix by any means, and we need to revisit how
we handle bindings to make it more uniform, but for now I think this is
a reasonable path to move forward.

Fixes a source compatibility regression.

rdar://problem/29960575
2017-01-31 23:52:29 -08:00
Slava Pestov
5cbaa9d7a6 Sema: When simplifying types, build ErrorTypes for failed conformance lookups 2017-01-28 18:35:23 -08:00
John McCall
39b65f49a0 Track the actual DC of a member access in the constraint system.
Without this, CSGen/CSSimplify and CSApply may have differing
opinions about whether e.g. a let property is settable, which
can lead to invalid ASTs.

Arguably, a better fix would be to remove the dependency on the
exact nested DC.  For example, we could treat lets as settable
in all contexts and then just complain later about invalid
attempts to set them.  Or we could change CSApply to directly
use the information it already has about how an l-value is used,
rather than trying to figure out whether it *might* be getting set.
But somehow, tracking a new piece of information through the
entire constraint system seems to be the more minimal change.

Fixes rdar://29810997.
2017-01-26 00:14:21 -05:00
Slava Pestov
8de0ca54e5 Sema: Merge the two implementations of simplifyType()
ConstraintSystem::simplifyType() replaced types with their fixed types
from the global map.

Solution::simplifyType() replaced types with their fixed types from the
current bindings.

There were some minor differences between the two, and some dead code.
2017-01-19 20:07:06 -08:00
Slava Pestov
a22b46244c Sema: Don't canonicalize base type in member lookup
We would lose ParenType sugar in function types as a result.

Fixes part of <rdar://problem/29739905>.
2017-01-19 20:07:05 -08:00
Hugh Bellamy
2445862e1b FIx recently introduced MSVC control path warnings 2017-01-14 12:40:41 +00:00
Roman Levenstein
29180ca1a0 Add support for layout requirements with layout constraints.
This commit introduces new kind of requirements: layout requirements.

This kind of requirements allows to expose that a type should satisfy certain layout properties, e.g. it should be a trivial type, have a given size and alignment, etc.
2017-01-11 19:21:45 -08:00
Slava Pestov
7731d4c6cb Sema: Remove some unnecessary calls to getCanonicalType() 2017-01-08 21:01:13 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Slava Pestov
edeb157964 Sema: Fix call to Self-returning methods with refined protocols
Regression from the following commit:

<9db06ee36d>

Fixes <rdar://problem/29868979>.
2017-01-04 15:48:38 -08:00
Slava Pestov
18adb53226 Sema: Tighten up name lookup routines to not look through metatypes/lvalues/etc
Previously all of the following would strip off varying amounts of
MetatypeType, LValueType, InOutType, DynamicSelfType, etc:

- ConstraintSystem::performMemberLookup()
- ConstraintSystem::lookupMember()
- TypeChecker::lookupMember()
- DeclContext::lookupQualified()
- Type::getContextSubstitutions()

The problem is that the higher level methods that took a lookup type
would call the lower level methods, and post-process the result using
the given lookup type. Since different levels of sugar were stripped,
it made the code hard to reason about and opened up edge cases, eg
if a DynamicSelfType or InOutType appears where we didn't expect it.

Since filtering out static/instance and mutating/nonmutating members
is done at higher levels, there's no reason for these name lookup
operations to accept anything other than nominal types, existentials
and archetypes.

Make this so with assertions, and deal with the fallout.
2017-01-04 01:40:19 -08:00
Slava Pestov
71df32fd7d Sema: Add some asserts 2017-01-04 01:08:28 -08:00
Slava Pestov
e455085d94 Sema: When opening an UnboundGenericType, don't put replacements in the same map
When inserting a new value, assert that there's no existing
value at that key, and to avoid the assert firing when
opening up UnboundGenericTypes, put those replacements in
their own map. We don't need them later.
2017-01-03 23:40:46 -08: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
Slava Pestov
eb78182afb Merge pull request #6510 from xedin/crasher-28592
[QoI] Fix recursive propagation of materializability to look through optional types
2017-01-03 18:58:16 -08:00
Joe Groff
796df2dc44 Merge pull request #6429 from jckarter/type-of-by-overload-resolution
`withoutActuallyEscaping`
2017-01-03 18:47:29 -08:00
Slava Pestov
bd53d2acd4 Merge pull request #6491 from xedin/crasher-28544
[TypeChecker] Fix isAnyHashableType to check type variables
2017-01-03 18:13:28 -08:00
Slava Pestov
a598ed68e6 Sema: Fixes for generic typealiases and nested type lookup
This patch contains several intertwined changes:

- Remove some unnecessary complexity and duplication.

- Adds a new TypeChecker::lookupUnqualifiedType() which bypasses most of
  the logic in TypeChecker::lookupUnqualified(), such as the
  LookupResultBuilder. Use this when resolving unqualified references
  to types.

- Fixes for generic typealiases to better preserve the type parameters of
  the parent type, and clean up the logic for applying the inner generic
  arguments. Some uses of generic typealiases that used to crash now work,
  and those tests have been uncommented.

- Avoid an unnecessary desugaring of TypeAliasDecls which map directly
  to GenericTypeParamTypes. Once again this perturbs the source-stability
  test.

- When looking up a nested type of a base class with a derived class base,
  always use the base class as the parent of the nested type. This fixes
  a recent regression where in some cases we were using the wrong parent.

Fixes <rdar://problem/29782186>.
2017-01-03 16:57:42 -08:00
Pavel Yaskevich
8c4b8715c6 [QoI] Fix recursive propagation of materializability to look through optional types
If T0 must be materializable and it's bound to T1, when matching T0 to
possibly optinal T1, look through optinality when setting materializability of the binding.
2016-12-29 22:55:12 -08:00
Pavel Yaskevich
dab14d3759 [TypeChecker] Fix isAnyHashableType to check type variables
Currently isAnyHashableType method validates only structs but
it doesn't account for situation when type is represented via type
variable with type already fixed to AnyHashable, that results in
infinite loop in the solver because restriction [hashable-to-
anyhashable] is going to add new type variable recursively.
2016-12-26 01:16:56 -08:00
Joe Groff
0c9297862f Sema: Handle type-checking for withoutActuallyEscaping.
withoutActuallyEscaping has a signature like `<T..., U, V, W> (@nonescaping (T...) throws<U> -> V, (@escaping (T...) throws<U> -> V) -> W) -> W, but our type system for functions unfortunately isn't quite that expressive yet, so we need to special-case it. Set up the necessary type system when resolving an overload set to reference withoutActuallyEscaping, and if a type check succeeds, build a MakeTemporarilyEscapableExpr to represent it in the type-checked AST.
2016-12-22 17:51:26 -08:00
Joe Groff
1889fde228 Resolve type(of:) by overload resolution rather than parse hackery.
`type(of:)` has behavior whose type isn't directly representable in Swift's type system, since it produces both concrete and existential metatypes. In Swift 3 we put in a parser hack to turn `type(of: <expr>)` into a DynamicTypeExpr, but this effectively made `type(of:)` a reserved name. It's a bit more principled to put `Swift.type(of:)` on the same level as other declarations, even with its special-case type system behavior, and we can do this by special-casing the type system we produce during overload resolution if `Swift.type(of:)` shows up in an overload set. This also lays groundwork for handling other declarations we want to ostensibly behave like normal declarations but with otherwise inexpressible types, viz. `withoutActuallyEscaping` from SE-0110.
2016-12-22 16:28:31 -08:00
Doug Gregor
8afeadc5ee Merge pull request #6309 from DougGregor/as-coercions-bridging
[Type checker] Clean up as/as!/as?/is casting
2016-12-21 15:53:18 -08:00
practicalswift
b253b21014 [gardening] Make sure argument names in comments match the actual parameter names 2016-12-21 22:56:01 +01:00
Doug Gregor
642c8ed3eb [Constraint solver] Collapse getBaseTypeFor(Array|Set)Type into is(Array|Set)Type.
Follow the pattern set by isDictionaryType() of performing the query
and extracting the underlying key/element types directly. We often
need both regardless. NFC
2016-12-21 13:46:13 -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
38be6125e5 [gardening] C++ gardening: Terminate namespaces, fix argument names, ...
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.
2016-12-17 00:32:42 +01:00