Commit Graph

74 Commits

Author SHA1 Message Date
Hamish Knight
18531b6bd3 [Sema] Enforce PatternTypeRequest returns contextual type
A bunch of synthesis code was getting this wrong
and setting an interface type for a TypedPattern.
Assert that we have a contextual type, and update
some synthesis logic.
2024-07-06 23:18:17 +01:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Meghana Gupta
c8ece100ba Handle explicit lifetime dependence specifiers in initializers 2024-02-02 11:50:10 -08:00
Hamish Knight
c97d80b1c3 [AST] NFC: Add convenience constructors for ReturnStmt
Add `ReturnStmt::createParsed` and `createImplict`.
2024-01-23 19:30:18 +00:00
Anthony Latsis
bd2f48d9d2 [NFC] AST: Introduce and use Identifier::isConstructor 2023-12-25 21:09:17 +03:00
Doug Gregor
ef642098f2 [Typed throws] Parsing and AST representation for typed errors
Parse typed throw specifiers as `throws(X)` in every place where there
are effects specified, and record the resulting thrown error type in
the AST except the type system. This includes:
* `FunctionTypeRepr`, for the parsed representation of types
* `AbstractFunctionDecl`, for various function-like declarations
* `ClosureExpr`, for closures
* `ArrowExpr`, for parsing of types within expression context

This also introduces some serialization logic for the thrown error
type of function-like declarations, along with an API to extract the
thrown interface type from one of those declarations, although right
now it will either be `Error` or empty.
2023-09-29 10:51:51 -07:00
Allan Shortlidge
0dd8f4c492 AST: Introduce abstraction for extension/type decl inheritance clauses.
Wrap the `InheritedEntry` array available on both `ExtensionDecl` and
`TypeDecl` in a new `InheritedTypes` class. This class will provide shared
conveniences for working with inherited type clauses. NFC.
2023-09-06 10:41:57 -07:00
Allan Shortlidge
7996c5b30c Sema: Avoid decoding unavailable enum elements in derived Codable conformances.
The compiler derived implementations of `Codable` conformances for enums did
not take enum element unavailability into account. This could result in
unavailable values being instantiated at runtime, leading to a general
violation of the invariant that unavailable code is unreachable at runtime.
This problem is possible because synthesized code is not type checked; had the
conformances been hand-written, they would have been rejected for referencing
unavailable declarations inside of available declarations.

This change specifically alters derivation for the following declarations:
- `Decodable.init(from:)`
- `Encodable.encode(to:)`
- `CodingKey.init(stringValue:)`

Resolves rdar://110098469
2023-07-26 22:48:25 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Hamish Knight
98855963ac [Sema] Introduce EnumElementExprPatternRequest
This is needed to ensure we only ever synthesize
a single unique ExprPattern when solving an
EnumElementPattern that we failed to lookup a
member for.
2023-03-07 15:16:36 +00:00
Hamish Knight
37b0a6074f [Sema] Introduce ExprPatternMatchRequest
This replaces `synthesizeTildeEqualsOperatorApplication`,
and synthesizes the match expression and var
on-demand.

Additionally, it pushes the lookup logic into
pre-checking.
2023-03-07 15:16:35 +00:00
Hamish Knight
9b8bc6033c [AST] NFC: Refactor ExprPattern construction
Introduce 3 separate factory constructors, and
remove the ability to specify the match expr and
var, as those should be synthesized on-demand.
2023-03-01 15:53:41 +00:00
Robert Widmann
2d256cb6c7 [NFC] Hide VarDecl::setIntroducer 2022-03-14 18:14:01 -07:00
Hamish Knight
47754822c7 [CodeSynthesis] Adopt ArgumentList
Most of this should be fairly mechanical, the
changes in PlaygroundTransform are a little more
involved though.
2021-09-01 18:40:26 +01:00
Alex Hoppen
1504870004 Merge pull request #36973 from ahoppen/pr/create-implicit-switch-stmt
[AST] Add method to create an implicit `SwitchStmt`
2021-04-22 11:42:08 +02:00
Alex Hoppen
aa69529809 [AST] Add method to create an implicit SwitchStmt
There are a number of occurances that create implicit `Switch`s by passing `SourceLoc()` for all location paramters. Refactor those occurances out to a separate `createImplicit` method that automatically fills the locations with invalid source locations.
2021-04-20 22:34:09 +02:00
Azoy
9ed732f0ab Introduce isDecl and getDeclType
fix enum logic issue

fix tests

guard against null types
2021-04-20 02:22:16 -04:00
Alex Hoppen
282cbc3590 Merge pull request #36930 from ahoppen/pr/complete-switch-expr-in-closure
[Parse] Create SwitchStmt nodes for `switch` statements with errors
2021-04-16 10:44:00 +02:00
Kavon Farvardin
4f6eb85fe3 allow type initializers to be 'async'
implicit calls to an async super.init are not allowed
2021-04-15 10:08:53 -07:00
Alex Hoppen
931f3394d7 [Parse] Create SwitchStmt nodes for switch statements with errors
At the moment, if there is an error in the `switch` statement expression or if the `{` is missing, we return `nullptr` from `parseStmtSwitch`, but we consume tokens while trying to parse the `switch` statement. This causes the AST to not contain any nodes for the tokens that were consumed while trying to parse the `switch` statement.

While this doesn’t cause any issues during compilation (compiling fails anyway so not having the `switch` statement in the AST is not a problem) this causes issues when trying to complete inside an expression that was consumed while trying to parse the `switch` statement but doesn’t have a representation in the AST. The solver-based completion approach can’t find the expression that contains the completion token (because it’s not part of the AST) and thus return empty results.

To fix this, make sure we are always creating a `SwitchStmt` when consuming tokens for it.

Previously, one could always assume that a `SwitchStmt` had a valid `LBraceLoc` and `RBraceLoc`. This is no longer the case because of the recovery. In order to form the `SwitchStmt`’s `SourceRange`, I needed to add a `EndLoc` property to `SwitchStmt` that keeps track of the last token in the `SwitchStmt`. Theoretically we should be able to compute this location by traversing the right brace, case stmts, subject expression, … in reverse order until we find something that’s not missing. But if the `SubjectExpr` is an `ErrorExpr`, representing a missing expression, it might have a source range that points to one after the last token in the statement (this is due to the way the `ErrorExpr` is being constructed), therefore returning an invalid range. So overall I thought it was easier and safer to add another property.

Fixes rdar://76688441 [SR-14490]
2021-04-15 18:37:25 +02:00
Slava Pestov
45fc0bc4db Sema: Replace some calls to getDeclaredType() with getDeclaredInterfaceType() 2020-07-31 13:39:02 -04:00
Slava Pestov
b50789404b Sema: Fix a few places where we built AST that had to go through SanitizeExpr before type checking 2020-06-26 07:42:21 -04:00
Robert Widmann
2371e5c260 Strip TypeLoc from EnumElementPattern 2020-06-10 14:22:46 -07:00
Robert Widmann
0342855e50 [NFC] Debride Pattern.h of Implicit Tri-State
Remove all of this in favor of explicit constructors to preserve the one-liners, or distribute the setImplicit() calls to the callsites if necessary.
2020-04-30 22:03:55 -07:00
Anthony Latsis
74252028ca AST: Rename getFullName -> getName on ValueDecl & MissingMemberDecl 2020-04-23 05:16:55 +03:00
Owen Voorhees
43e2d107e1 [SE-0276] Implement multi-pattern catch clauses
Like switch cases, a catch clause may now include a comma-
separated list of patterns. The body will be executed if any
one of those patterns is matched.

This patch replaces `CatchStmt` with `CaseStmt` as the children
of `DoCatchStmt` in the AST. This necessitates a number of changes
throughout the compiler, including:
- Parser & libsyntax support for the new syntax and AST structure
- Typechecking of multi-pattern catches, including those which
  contain bindings.
- SILGen support
- Code completion updates
- Profiler updates
- Name lookup changes
2020-04-04 09:28:26 -07:00
Brent Royal-Gordon
addbe3e5ed [NFC] Thread DeclNameRef through most of the compiler
This huge commit contains as many of the mechanical changes as possible.
2019-12-11 00:55:18 -08:00
Brent Royal-Gordon
8551b32af2 [NFC] Make EnumElementPattern carry a DeclName
This has the side effect of threading compound name support through more enum pattern code, although it’s still not complete.
2019-12-11 00:45:07 -08:00
Brent Royal-Gordon
a3035eb925 [NFC] Add helpers for unresolved AST node synthesis
This change adds UnresolvedDotExpr::createImplicit() and UnresolvedDeclRefExpr::createImplicit() helpers. These calls simplify several tedious bits of code synthesis that would otherwise become even more tedious with DeclNameRef in the picture.
2019-12-11 00:45:07 -08:00
Robert Widmann
2f2b8afad8 Remove the list of synthesized decls"
This used to be a lot more relevant a long time ago when typeCheckFunctionsAndExternalDecls actually did type check external functions defined in C.  Now, it serves no purpose.

The validation order change from just type checking these things eagerly doesn't seem to affect anything.
2019-11-11 11:33:59 -08:00
Slava Pestov
ae8c85ef80 Sema: Remove some unnecessary (void) getInterfaceType() calls 2019-11-04 14:59:01 -05:00
Robert Widmann
7993f2ffeb Downgrade the TypeChecker in DerivedConformance to an ASTContext 2019-10-30 12:55:42 -07:00
Robert Widmann
497a2227ba [NFC] Remove AbstractFunctionDecl::computeType()
Its functionality is entirely subsumed by InterfaceTypeRequest.
2019-10-21 12:15:50 -07:00
Slava Pestov
87cc09c02b AST: Remove some unnecessary calls to setGenericSignature() 2019-10-10 19:54:48 -04:00
Slava Pestov
d8b61ff24b Sema: Peel off typeCheckParameterList()'s specifier computation into a request
Since getSpecifier() now kicks off a request instead of always
returning what was previously set, we can't pass a ParamSpecifier
to the ParamDecl constructor anymore. Instead, callers either
call setSpecifier() if the ParamDecl is synthesized, or they
rely on the request, which can compute the specifier in three
specific cases:

- Ordinary parsed parameters get their specifier from the TypeRepr.

- The 'self' parameter's specifier is based on the self access kind.

- Accessor parameters are either the 'newValue' parameter of a
  setter, or a cloned subscript parameter.

For closure parameters with inferred types, we still end up
calling setSpecifier() twice, once to set the initial defalut
value and a second time when applying the solution in the
case that we inferred an 'inout' specifier. In practice this
should not be a big problem because expression type checking
walks the AST in a pre-determined order anyway.
2019-10-10 15:00:07 -04:00
Slava Pestov
6702d38d87 Sema: Remove most calls to Decl::setValidationToChecked() 2019-10-03 17:11:45 -04:00
Robert Widmann
1233cdf596 Update SourceKit for getInterfaceType() changes 2019-09-23 17:24:18 -07:00
Robert Widmann
f053f9c480 Port getInterfaceType() patterns in libSema 2019-09-23 16:49:29 -07:00
Slava Pestov
f292c1b240 AST: Remove GenericContext::setGenericEnvironment()
This was a transitional step before converting all callers to
store a generic signature instead of an environment.
2019-09-06 17:16:04 -04:00
Slava Pestov
1c3ac86796 AST: Banish OptionalTypeKind to ClangImporter.h
The only place this was used in Decl.h was the failability kind of a
constructor.

I decided to replace this with a boolean isFailable() bit. Now that
we have isImplicitlyUnwrappedOptional(), it seems to make more sense
to not have ConstructorDecl represent redundant information which
might not be internally consistent.

Most callers of getFailability() actually only care if the result is
failable or not; the few callers that care about it being IUO can
check isImplicitlyUnwrappedOptional() as well.
2019-08-15 18:41:42 -04:00
Slava Pestov
1ee2db4520 AST: Accessors no longer appear as members of their parent DeclContext
Accessors logically belong to their storage and can be synthesized
on the fly, so removing them from the members list eliminates one
source of mutability (but doesn't eliminate it; there are also
witnesses for derived conformances, and implicit constructors).

Since a few ASTWalker implementations break in non-trivial ways when
the traversal is changed to visit accessors as children of the storage
rather than peers, I hacked up the ASTWalker to optionally preserve
the old traversal order for now. This is ugly and needs to be cleaned up,
but I want to avoid breaking _too_ much with this commit.
2019-07-30 15:56:00 -04:00
Slava Pestov
a532a325e1 AST: Move a few methods from VarDecl down to ParamDecl 2019-07-22 20:19:09 -04:00
Doug Gregor
8117849d46 [AST] Make function body synthesizers less stateful.
Instead of requiring that function body synthesizers will always call
setBody(), which is annoyingly stateful, have function body synthesizers
always return the synthesized brace statement along with a bit that
indicates whether the body was already type-checked. This takes us a
step closer to centralizing the mutation of the body of a function.
2019-07-11 21:31:21 -07:00
Slava Pestov
4c499fd4ac AST: Stop passing around LazyResolvers in various places 2019-07-06 00:43:22 -04:00
Michael Gottesman
b50d878f5d [parse/sema] Give all case bodies their own var decls without using those var decls for anything.
This is a step in the direction of fixing the fallthrough bug. Specifically, in
this commit I give case stmts a set of var decls for the bodies of the case
statement. I have not wired them up to anything except the var decl
list/typechecking.

rdar://47467128
2019-03-25 10:30:57 -07:00
Slava Pestov
6f243d4ab3 AST: Plumb a 'context' parameter through to AbstractFunctionBody's body synthesizer 2018-12-07 17:10:08 -05:00
Slava Pestov
c360c82850 AST: Automatically create the 'self' parameter when needed
Parsed declarations would create an untyped 'self' parameter;
synthesized, imported and deserialized declarations would get a
typed one.

In reality the type, if any, depends completely on the properties
of the function in question, so we can just lazily create the
'self' parameter when needed.

If the function already has a type, we give it a type right there;
otherwise, we check if a 'self' was already created when we
compute a function's type and set the type of 'self' then.
2018-08-25 10:44:55 -07:00
Jordan Rose
537954fb93 [AST] Rename several DeclContext methods to be clearer and shorter (#18798)
- getAsDeclOrDeclExtensionContext -> getAsDecl

This is basically the same as a dyn_cast, so it should use a 'getAs'
name like TypeBase does.

- getAsNominalTypeOrNominalTypeExtensionContext -> getSelfNominalTypeDecl
- getAsClassOrClassExtensionContext -> getSelfClassDecl
- getAsEnumOrEnumExtensionContext -> getSelfEnumDecl
- getAsStructOrStructExtensionContext -> getSelfStructDecl
- getAsProtocolOrProtocolExtensionContext -> getSelfProtocolDecl
- getAsTypeOrTypeExtensionContext -> getSelfTypeDecl (private)

These do /not/ return some form of 'this'; instead, they get the
extended types when 'this' is an extension. They started off life with
'is' names, which makes sense, but changed to this at some point.  The
names I went with match up with getSelfInterfaceType and
getSelfTypeInContext, even though strictly speaking they're closer to
what getDeclaredInterfaceType does. But it didn't seem right to claim
that an extension "declares" the ClassDecl here.

- getAsProtocolExtensionContext -> getExtendedProtocolDecl

Like the above, this didn't return the ExtensionDecl; it returned its
extended type.

This entire commit is a mechanical change: find-and-replace, followed
by manual reformatted but no code changes.
2018-08-17 14:05:24 -07:00
Slava Pestov
4b258e86e6 AST: Stop setting contextual types on ParamDecls
VarDecl::getType() lazily maps the interface type into context if needed.
2018-08-10 13:33:12 -07:00
Slava Pestov
1b7fbb45e6 Sema: Use AbstractFunctionDecl::computeType() 2018-07-23 02:09:43 -07:00