Commit Graph

85 Commits

Author SHA1 Message Date
Robert Widmann
874cc856f0 Make LookupInModuleRequest a Dependency Sink
It wasn't one in the past because the referenced name tracker was written into by unqualified lookup, which would delegate to this request. Now that it's no longer doing that, we have to capture this edge here for private dependencies.
2020-06-04 20:17:46 -07:00
Hamish Knight
9e2cdf49b3 Merge pull request #31506 from hamishknight/hello-operator 2020-05-23 09:48:21 -07:00
Robert Widmann
0a7929e80f Refine Naive Dependency Collection Algorithm
Split off the notion of "recording" dependencies from the notion of
"collecting" dependencies. This corrects an oversight in the previous
design where dependency replay and recording were actually not "free" in
WMO where we actually never track dependencies. This architecture also
lays the groundwork for the removal of the referenced name trackers.

The algorithm builds upon the infrastructure for dependency sources and
sinks laid down during the cut over to request-based dependency tracking
in #30723.

The idea of the naive algorithm is this:

For a chain of requests A -> B* -> C -> D* -> ... -> L where L is a lookup
request and all starred requests are cached, once L writes into the
dependency collector, the active stack is walked and at each cache-point
the results of dependency collection are associated with the request
itself (in this example, B* and D* have all the names L found associated
with them). Subsequent evaluations of these cached requests (B* and D*
et al) will then *replay* the previous lookup results from L into the
active referenced name tracker. One complication is, suppose the
evaluation of a cached request involves multiple downstream name
lookups. More concretely, suppose we have the following request trace:

A* -> B -> L
      |
       -> C -> L
          |
           -> D -> L
              |
               -> ...

Then A* must see the union of the results of each L. If this reminds
anyone of a union-find, that is no accident! A persistent union-find
a la Conchon and Filliatre is probably in order to help bring down peak
heap usage...
2020-05-20 16:08:05 -07:00
Hamish Knight
cc062ee2bb Fix precedencegroup and operator decl lookup
Re-implement operator and precedencegroup decl
lookup to use `namelookup::getAllImports` and
existing decl shadowing logic. This allows us to
find operator decls through `@_exported` imports,
prefer operator decls defined in the same module
over imported decls, and fixes a couple of other
subtle issues.

Because this new implementation is technically
source breaking, as we can find multiple results
where we used to only find one result, it's placed
behind the new Frontend flag
`-enable-new-operator-lookup` (with the aim of
enabling it by default when we get a new language
mode).

However the new logic will always be used if the
result is unambiguous. This means that e.g
`@_exported` operators will be instantly available
as long as there's only one candidate. If multiple
candidates are found, we fall back to the old
logic.

Resolves SR-12132.
Resolves rdar://59198796.
2020-05-18 14:33:43 -07:00
Robert Widmann
7a724b1477 [NFC] Extract Dependency Registration to DependencyCollector
Define a new type DependencyCollector that abstracts over the
incremental dependency gathering logic. This will insulate the
request-based name tracking code from future work on private,
intransitive dependencies.
2020-04-22 21:01:20 -07:00
Robert Widmann
ee723cd953 Document Some Whys
* Document a number of legacy conditions and edge cases

* Add lexicon definitions for "dependency source", "dependency sink",
"cascading dependency" and "private dependency"
2020-03-31 16:19:13 -07:00
Robert Widmann
2b0ca2ae65 Add the active tracker to the dependency sink points 2020-03-31 16:16:53 -07:00
Robert Widmann
8c69814f5c Define Dependency Sinks
Convert most of the name lookup requests and a few other ancillary typechecking requests into dependency sinks.

Some requests are also combined sinks and sources in order to emulate the current scheme, which performs scope changes based on lookup flags. This is generally undesirable, since it means those requests cannot immediately be generalized to a purely context-based scheme because they depend on some client-provided entropy source. In particular, the few callers that are providing the "known private" name lookup flag need to be converted to perform lookups in the appropriate private context.

Clients that are passing "no known dependency" are currently considered universally incorrect and are outside the scope of the compatibility guarantees. This means that request-based dependency tracking registers strictly more edges than manual dependency tracking. It also means that once we fixup the clients that are passing "known private", we can completely remove these name lookup flags.

Finally, some tests had to change to accomodate the new scheme. Currently, we go out of our way to register a dependency edge for extensions that declare protocol conformances. However, we were also asserting in at least one test that extensions without protocol conformances weren't registering dependency edges. This is blatantly incorrect and has been undone now that the request-based scheme is automatically registering this edge.
2020-03-31 16:16:53 -07:00
Robert Widmann
987cd55f50 [NFC] Drop llvm::Expected from Evaluation Points
A request is intended to be a pure function of its inputs. That function could, in theory, fail. In practice, there were basically no requests taking advantage of this ability - the few that were using it to explicitly detect cycles can just return reasonable defaults instead of forwarding the error on up the stack.

This is because cycles are checked by *the Evaluator*, and are unwound by the Evaluator.

Therefore, restore the idea that the evaluate functions are themselves pure, but keep the idea that *evaluation* of those requests may fail. This model enables the best of both worlds: we not only keep the evaluator flexible enough to handle future use cases like cancellation and diagnostic invalidation, but also request-based dependencies using the values computed at the evaluation points. These aforementioned use cases would use the llvm::Expected interface and the regular evaluation-point interface respectively.
2020-03-26 23:08:02 -07:00
Robert Widmann
302b7f5bf9 [NFC] Define InheritedProtocolsRequest
Refactor the interface to ProtocolDecl::getInheritedProtocols in
preparation for request-based dependency tracking.
2020-03-23 18:49:23 -07:00
Robert Widmann
d4bc0a62c5 [NFC] Define LookupConformanceInModuleRequest
Factor out the lookup side of TypeChecker::conformsToProtocol so we have
a dependency registration point available for evaluator-based
dependencies that doesn't have re-entrancy problems.
2020-03-23 16:24:17 -07:00
Hamish Knight
9656a0491e Allow OperatorLookupDescriptor to hold a file or module 2020-03-23 09:17:58 -07:00
Robert Widmann
bfe23bba5b Define LookupOperatorRequest and Friends
Turn macro metaprogramming into template metaprogramming by defining a new kind of request that runs operator lookups.

This is the final piece of the puzzle for requestification of the current referenced name tracker system.
2020-03-20 15:50:12 -07:00
Robert Widmann
26d8bad7c2 Add DirectLookupRequest 2020-01-25 11:04:53 -08:00
Harlan Haskins
283854a012 [Sema] Requestify hasMissingDesignatedInitializers
We’re going to start serializing this for public types that have non-public-or-@usableFromInline initializers, so turn it into a request that we can query and cache it in the existing bit.
2020-01-06 10:15:07 -08:00
Hamish Knight
2853615880 Add type to package inputs to UnqualifiedLookupRequest
This allows us use an OptionSet parameter for
the request (as currently we can't directly use it
as a parameter due to not having an == definition
for it). It also allows us to regain default
arguments for the source loc and flag parameters.
2019-11-15 16:35:14 -08:00
Robert Widmann
6bb0e49eab Move precedence group cycle checking into requests
Use the request evaluator to get the easier in-module precedence group cycles.   Unfortunately, cross-module precedence group cycles are still a possibility, and do not actually cause cyclic request evaluation, so we cannot completely erase the old diagnostics machinery.

Move the machinery itself into the type checker and shift the request into that zone as well to appease the linker.
2019-10-18 11:19:25 -07:00
David Ungar
ea81fdc7d8 Merge pull request #27313 from davidungar/generic-request-or-extended-nominal-assertion
Fail early if getExtendedNominal is called before extension has been bound.
2019-09-30 08:37:33 -07:00
David Ungar
4bc4030338 Catch failures earlier caused by premature requests for extended nominal 2019-09-28 15:19:32 -07:00
Robert Widmann
7d2dac1272 Define Requests
Define the LookupPrecedenceGroupRequest and OperatorPrecedenceGroupRequest for looking up an unvalidated precedence group declaration and retrieving then validating the precedence group associated with an operator.

This allows us to drop both validateDecl overloads for these types out of the TypeChechecker
2019-09-24 17:45:14 -07:00
Robert Widmann
d4bb9a5cfe Define GenericParamListRequest
GenericParamListRequest formalizes the lazy generic parameter list construction pattern we were performing before.
2019-09-06 17:22:30 -07:00
Robert Widmann
c25e21840a Convert some TypeLoc computations to helpers
These aren't requirements of the (Simple)Request interface.  Downgrade
them to helper functions.
2019-09-06 11:16:17 -07:00
Robert Widmann
087e2f2746 [Evaluator Ergonomics] Add location information options to the requests 2019-09-06 11:16:17 -07:00
Robert Widmann
7a51cfcb87 [Evaluator Ergonomics] Add Request Signatures
Also add their caching kinds.  This information will be used to remove
the need to define classes at all.
2019-09-05 13:15:02 -07:00
Robert Widmann
a19a70e5c9 Switch all request infrastructure to SWIFT_REQUEST
Formally define the Zones in the TypeID header.  This is not its final
resting place.
2019-08-27 17:38:14 -07:00
Slava Pestov
0063f158be AST: Request-ify synthesis of the implicit destructor 2019-08-09 19:08:47 -04:00
Doug Gregor
39d4e6b41d [Request-evaluator] Remove extraneous diagnoseCycle/noteCycleStep impls.
All of these can use the default implementations now.
2019-07-10 17:26:39 -07:00
Doug Gregor
052068edb8 [Request-evaluator] Provide defaults for diagnoseCycle/noteCycleStep.
Introduce some template metaprogramming infrastructure to retrieve the
"nearest" source location to the inputs of a request, and use that to
provide default diagnoseCycle and noteCycleStep implementations. This
will help remove a bunch of boilerplate from new requests.
2019-07-10 17:25:51 -07:00
Doug Gregor
a848d12665 Parse unknown attributes as "custom" attributes.
Parse custom attributes with the grammar:

```
'@' type-identifier expr-paren?
```
2019-03-29 23:10:36 -07:00
Slava Pestov
a8d1910552 AST: Cache SuperclassDeclRequest
This fixes a significant build time regression since 4.2.

Fixes <rdar://problem/47305605>.
2019-01-15 23:24:36 -05:00
Slava Pestov
36c8d94238 AST: Refactor SelfBoundsFromWhereClause to support ProtocolDecls 2018-10-12 03:06:52 -07:00
Slava Pestov
cdadee8173 AST: Fix layering violations in DefaultAndMaxAccessLevelRequest
Our walk over the requirement interface types meant that
computing the access level of an extension member depended
on type resolution and the GSB.

Fix this by adding a new request that simply collects all
TypeDecls referenced from a TypeRepr, and compute the
extension's maximum access level using that.

If we use Structural rather than Interface type resolution when
walking the extension's requirements, we don't have to build its
generic signature first.
2018-09-05 16:18:54 -07:00
Doug Gregor
5b6b0b6ab1 [Name lookup] Turn the "Self bounds of a where clause" query into a request.
Name lookup within a protocol extension also looks into protocols and
superclasses on the right-hand side of Self constraints in the where
clause, e.g., "Self: Foo". Turn that function into a request to avoid
infinite recursion on invalid code.
2018-08-13 19:03:35 -07:00
Doug Gregor
84cb19758e [Name lookup] Introduce a request for “extended nominal type decl”.
Introduce a request for ExtensionDecl::getExtendedNominal() that
uses TypeRepr-based resolution to find the extended nominal
type declaration without going through type resolution.
2018-08-03 11:26:48 -07:00
Doug Gregor
cb7c2b4fce [Name lookup] Introduce requests for several name lookup operations.
Introduce three new requests for name lookup operations that avoid performing
type checking/semantic analysis. They work using syntactic information
(e.g., TypeReprs) and AST-level name lookup operations that will (eventually)
avoid and calls back into type checking. The new requests are:

* Retrieve the superclass declaration of a protocol or class declaration. Use
this request for ClassDecl::getSuperclassDecl() and
ProtocolDecl::getSuperclassDecl().
* Retrieve the types “directly referenced” by a particular location in
an inheritance clause. This query is based on looking at the TypeReprs
and performing fairly-minimal lookup, so it does not involve any Type
computations.
* Retrieve the types “directly referenced” by the underlying type of
a typealias. This query allows us to desugar a typealias without forming
a type.

Along with these is a core operation to transform a set of TypeDecl*s
into a set of NominalTypeDecl*s, looking through typealiases, and
without involving Type at all. The superclass-decl request does this
to find a ClassDecl; other requests will eventually do this to (e.g.)
find all of the protocols mentioned in an inheritance clause.
2018-07-31 10:14:44 -07:00