Commit Graph

72 Commits

Author SHA1 Message Date
Becca Royal-Gordon
413c673da4 [NFC] Requestify ABI role computation 2024-12-19 21:22:08 -08:00
Slava Pestov
b7117aa877 AST: Start untangling ModuleDecl from conformance lookup 2024-07-06 12:05:45 -04:00
Slava Pestov
17a6a80204 AST: Use separate caching for ProtocolDecl::getAllInheritedProtocols() 2024-06-25 15:20:42 -04:00
Becca Royal-Gordon
07b9fe9ce6 Support @objc(CustomName) on extensions
This now specifies a category name that’s used in TBDGen, IRGen, and PrintAsClang. There are also now category name conflict diagnostics; these subsume some @implementation diagnostics.

(It turns out there was already a check for @objc(CustomName) to make sure it wasn’t a selector!)
2024-05-16 13:40:13 -07:00
Slava Pestov
443919a9bf AST: Introduce ProtocolDecl::getAllInheritedProtocols() 2024-02-24 07:25:59 -05:00
Slava Pestov
7909d83229 AST: Refactor directReferencesForTypeRepr() to track inverses 2024-02-24 07:25:59 -05: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
Pavel Yaskevich
9e056a1fa2 [SILGen] NFC: Convert intrinsic function lookup into a request 2024-01-22 11:25:49 -08: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
Holly Borla
cd752cca22 [NameLookup] Plumb source location arguments through all name lookup APIs.
This source location will be used to determine whether to add a name lookup
option to exclude macro expansions when the name lookup request is constructed.
Currently, the source location argument is unused.
2023-06-11 23:09:47 -07:00
Slava Pestov
7499c222ee AST: Requestify lookup of protocol referenced by ImplementsAttr
Direct lookup relied in primary file checking to have filled in the
protocol type stored in the ImplementsAttr. This was already wrong
with multi-file test cases in non-WMO mode, and crashed in the
ASTPrinter if printing a declaration in a non-primary file.

I don't have a standalone test case that is independent of my
upcoming ASTPrinter changes, but this is a nice cleanup regardless.
2023-06-02 13:17:25 -04:00
Doug Gregor
af3ea4d142 [Name lookup] Only walk types/extensions to expand macros when we need to
Keep track of which types/extensions have members that could be produced by
a macro expansion, including the names of those members. Use this to
avoid walking into extensions or type definitions to expand macros
when they don't have any related macros.
2023-05-31 15:37:46 -07:00
Doug Gregor
f96240d2d8 [Macros] Do not look into macro expansions while resolving macro arguments.
Macros introduced a significant wrinkle into Swift's name lookup mechanism.
Specifically, when resolving names (and, really, anything else) within the
arguments to a macro expansion, name lookup must not try to expand any
macros, because doing so trivially creates a cyclic dependency amongst the
macro expansions that will be detected by the request-evaluator.

Our lookup requests don't always have enough information to answer the
question "is this part of an argument to a macro?", so we do a much simpler,
more efficient, and not-entirely-sound hack based on the request-evaluator.
Specifically, if we are in the process of resolving a macro (which is
determined by checking for the presence of a `ResolveMacroRequest` in the
request-evaluator stack), then we adjust the options used for the name
lookup request we are forming to exclude macro expansions. The evaluation
of that request will then avoid expanding any macros, and not produce any
results that involve entries in already-expanded macros. By adjusting the
request itself, we still distinguish between requests that can and cannot
look into macro expansions, so it doesn't break caching for those immediate
requests.

Over time, we should seek to replace this heuristic with a location-based
check, where we use ASTScope to determine whether we are inside a macro
argument. This existing check might still be useful because it's going to
be faster than a location-based query, but the location-based query can be
fully correct.

This addresses a class of cyclic dependencies that we've been seeing
with macros, and aligns the lookup behavior for module-level lookups
with that specified in the macros proposals. It is not fully complete
because lookup until nominal types does not yet support excluding
results from macro expansions.
2023-04-06 16:04:41 -07:00
Holly Borla
3e6fdb8807 [NameLookup] The custom attribute lookup request only returns nominal types.
Macro attribute lookup is now implemented in ResolveMacroRequest, which happens
later because it needs overload resolution to resolve a custom attribute to a
macro decl.
2023-01-26 17:10:28 -08:00
Doug Gregor
69649a40a6 Generalize CustomAttrNominalRequest's name and signature to account for macros 2023-01-11 21:28:26 -08:00
Pavel Yaskevich
82f34b90c1 [AST] NameLookup: Add a request to gather protocol requirements 2022-11-04 11:11:41 -07:00
Hamish Knight
fe7c1f4b9b Refactor callable lookup
Move off `Type` based requests and onto `Decl`
based requests, utilizing name lookup's
`extractDirectlyReferencedNominalTypes` utility.
This allows us to better cache the results, and
avoids the need to guard against type variable
inputs when deciding whether or not to cache.
2022-07-25 22:03:55 +01:00
hank121314
ad00118d9a [Sema] TypeCheckProtoclInference: Using generic signature to check conformance instead of trailingWhereClause 2022-04-11 09:26:08 +08:00
Slava Pestov
d1a2a612b1 AST: Change some writeDependencySink() methods to take the result by const reference 2020-12-22 01:42:04 -05:00
Slava Pestov
0fa84c14a0 ASTScope: Remove the ExpandASTScopeRequest
This doesn't really fit the request evaluator model since the
result of evaluating the request is the new insertion point,
but we don't have a way to get the insertion point of an
already-expanded scope.

Instead, let's change the callers of the now-removed
expandAndBeCurrentDetectingRecursion() to instead call
expandAndBeCurrent(), while checking first if the scope was
already expanded.

Also, set the expanded flag before calling expandSpecifically()
from inside expandAndBeCurrent(), to ensure that re-entrant
calls to expandAndBeCurrent() are flagged by the existing
assertion there.

Finally, replace a couple of existing counters, and the
now-gone request counter with a single ASTScopeExpansions
counter to track expansions.
2020-12-18 15:43:33 -05:00
Arnold Schwaighofer
b994bf3191 Add support for _specialize(exported: true, ...)
This attribute allows to define a pre-specialized entry point of a
generic function in a library.

The following definition provides a pre-specialized entry point for
`genericFunc(_:)` for the parameter type `Int` that clients of the
library can call.

```
@_specialize(exported: true, where T == Int)
public func genericFunc<T>(_ t: T) { ... }
```

Pre-specializations of internal `@inlinable` functions are allowed.

```
@usableFromInline
internal struct GenericThing<T> {
  @_specialize(exported: true, where T == Int)
  @inlinable
  internal func genericMethod(_ t: T) {
  }
}
```

There is syntax to pre-specialize a method from a different module.

```
import ModuleDefiningGenericFunc

@_specialize(exported: true, target: genericFunc(_:), where T == Double)
func prespecialize_genericFunc(_ t: T) { fatalError("dont call") }

```

Specially marked extensions allow for pre-specialization of internal
methods accross module boundries (respecting `@inlinable` and
`@usableFromInline`).

```
import ModuleDefiningGenericThing
public struct Something {}

@_specializeExtension
extension GenericThing {
  @_specialize(exported: true, target: genericMethod(_:), where T == Something)
  func prespecialize_genericMethod(_ t: T) { fatalError("dont call") }
}
```

rdar://64993425
2020-10-12 09:19:29 -07:00
Doug Gregor
4ddf6e565a Teach SuperclassDeclRequest to always diagnose circularity.
Rather than relying on clients to cope with the potential for circular
inheritance of superclass declarations, teach SuperclassDeclRequest to
establish whether circular inheritance has occurred and produce "null"
in such cases. This allows other clients to avoid having to think about

To benefit from this, have SuperclassTypeRequest evaluate
SuperclassDeclRequest first and, if null, produce a Type(). This
ensures that we don't get into an inconsistent situation where there
is a superclass type but no superclass declaration.
2020-09-29 17:42:17 -07:00
Robert Widmann
fe5dacb280 Remove unnecessary dependency sources 2020-09-21 10:37:42 -06:00
Robert Widmann
ec885b027b [NFC] const-qualify Inheritance-Clause-Bearing PointerUnion 2020-07-23 20:45:24 -07:00
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
Hamish Knight
22c64640e0 Register operator dependencies on direct lookup requests
Make sure a dependency gets registered when a
direct lookup is fired off. This is necessary in
order to ensure that operator redeclaration
checking records the right dependencies (and any
future logic that might want to perform direct
operator lookups).

In doing so, this commit also removes the
compatibility logic for the old referenced name
tracker that would skip recording dependencies in
certain cases. This should be safe as the new
logic will record strictly more dependencies than
the old logic.
2020-04-30 15:27:51 -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
3d09a00a0a CacheKind -> RequestFlags 2020-03-31 16:16:53 -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
Hamish Knight
4e42f033a5 Switch operator lookup over to using SourceLookupCache
Switch the direct operator lookup logic over to
querying the SourceLookupCache, then switch the
main operator lookup logic over to calling the
direct lookup logic rather than querying the
operator maps on the SourceFile.

This then allows us to remove the SourceFile
operator maps, in addition to the logic from
NameBinding that populated them. This requires
redeclaration checking to be implemented
separately.

Finally, to compensate for the caching that the old
operator maps were providing for imported results,
turn the operator lookup requests into cached
requests.
2020-03-27 09:45:33 -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
cc9c851856 Add direct operator lookup requests
Introduce DirectOperatorLookupRequest &
DirectPrecedenceGroupLookupRequest that lookup
operator and precedence groups within a given
file or module without looking through imports.

These will eventually be used as the basis for the
new operator lookup implementation, but for now
just use them when querying lookup results from
serialized module files.
2020-03-23 09:17:58 -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
b09c9957ad Reintroduce NameLookupFlags::IgnoreNewExtensions
Soft revert a09382c. It should now be safe to add this flag back as an optimization to specifically disable lazy member loading instead of all extension loading.

Push the flag back everywhere it was needed, but also push it into lookup for associated type members which will never appear in extensions.
2020-01-25 11:04:53 -08: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
Robert Widmann
e7170bd751 Add Qualified Lookup Requests 2019-12-16 15:36:09 -08:00
Brent Royal-Gordon
da88512eda [NFC] Take DeclNameRef in UnqualifiedLookup and lookupQualified() 2019-12-11 00:55:17 -08:00
Brent Royal-Gordon
9a57554bdf [NFC] DeclNameRef-ify qualified and unqualified lookup 2019-12-11 00:55:17 -08:00
Hamish Knight
256c129506 [NameLookup] Add AnyObjectLookupRequest 2019-11-22 12:59:27 -08:00
Hamish Knight
e04b56bd67 [NameLookup] Add LookupInModuleRequest 2019-11-22 12:59:26 -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
Hamish Knight
633de0241b Add UnqualifiedLookupRequest
This request performs raw unqualified lookup,
and will be used to replace the UnqualifiedLookup
type.
2019-11-15 14:25:42 -08:00