`recordObjCOverride()` records semantic overrides for imported Obj-C methods.
Since these methods are imported from a different language, it doesn't make
sense to enforce Swift's member import visibility rules when performing lookups
to find overridden methods. Doing so caused the Constrain Solver to lack
important information needed to eliminate overloads, resulting in erroneous
ambiguities.
Resolves rdar://141636723.
Adjust the valid position checking and special handle EOF position.
If the requested location is at EOF, use the last token, but still
emit the diagnostics at the specificied location.
rdar://138426038
Find all the usages of `--enable-experimental-feature` or
`--enable-upcoming-feature` in the tests and replace some of the
`REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which
should correctly apply to depending on the asserts/noasserts mode of the
toolchain for each feature.
Remove some comments that talked about enabling asserts since they don't
apply anymore (but I might had miss some).
All this was done with an automated script, so some formatting weirdness
might happen, but I hope I fixed most of those.
There might be some tests that were `REQUIRES: asserts` that might run
in `noasserts` toolchains now. This will normally be because their
feature went from experimental to upcoming/base and the tests were not
updated.
Create some test cases that demonstrate MemberImportVisibility behavior with respect referencing inherited members. There are already tests that demonstrate overrides, but nothing seemed to show the behavior when referencing an inherted member through a derived type. I wanted to verify this behavior so I wrote a test to demonstrate it. It seems reasonable to check-in the test to ensure the behavior remains consistent.
Previously, the constraint solver would first attempt member lookup that
excluded members from transitively imported modules. If there were no viable
candidates, it would perform a second lookup that included the previously
excluded members, treating any candidates as unviable. This meant that if the
member reference did resolve to one of the unviable candidates the resulting
AST would be broken, which could cause unwanted knock-on diagnostics.
Now, members from transitively imported modules are always returned in the set
of viable candidates. However, scoring will always prioritize candidates from
directly imported modules over members from transitive imports. This solves the
ambiguities that `MemberImportVisibility` is designed to prevent. If the only
viable candidates are from transitively imported modules, though, then the
reference will be resolved successfully and diagnosed later in
`MiscDiagnostics.cpp`. The resulting AST will not contain any errors, which
ensures that necessary access levels can be computed correctly for the imports
suggested by `MemberImportVisibility` fix-its.
Resolves rdar://126637855.
If `OverriddenDeclsRequest` fails to find any overridden declarations, query
again ignoring missing imports to find declarations that were excluded due to the
`MemberImportVisibility` feature being enabled.
When `MemberImportVisibility` is enabled, if the import that would bring a
member declaration into scope is missing it is diagnosed as an error. The
existing resilience diagnostics that would also diagnose the same problem in
contexts that are visible in the module interface are therefore superflous with
the feature enabled.
Some editors use diagnostics from SourceKit to replace build issues. This causes issues if the diagnostics from SourceKit are formatted differently than the build issues. Make sure they are rendered the same way, removing most uses of `DiagnosticsEditorMode`.
To do so, always emit the `add stubs for conformance` note (which previously was only emitted in editor mode) and remove all `; add <something>` suffixes from notes that state which requirements are missing.
rdar://129283608
To improve knock-on diagnostics, resolve qualified types to their matching
member type declarations regardless of whether an import is missing when the
`MemberImportVisibility` features is enabled.
Part of rdar://126637855.
To improve knock-on diagnostics, resolve unqualified types to their matching
member type declarations regardless of whether an import is missing when the
`MemberImportVisibility` features is enabled.
Part of rdar://126637855.
When emitting fix-its for missing imports, include an access level when the
module has been imported with an access level in other source files. For now,
the suggested access level for will always be `internal`, even when uses of
members in the file would actually require `public` or `package` visibility. In
order to suggest the correct access level, name lookup will need to be
refactored to repair references to inaccessible declarations, instead of
leaving error nodes in the AST. In anticipation of that refactoring of name
lookup, missing import diagnostics are now delayed until type checking a source
file is finished so that a consistent access level can be suggested for each
import fix-it for a given module.
Partially resolves rdar://126637855.
In existing Swift, an `@_exported import` in any source file makes the
declarations from the imported module visible in all source files. It's unclear
whether this is an explicit decision or is simply and unintended consequence of
effectively adding an implicit import to each source file for the module being
compiled.
Although it's not clear whether this behavior is desirable, the behavior of
member lookup when the MemberImportVisibility feature is enabled should align
with it in order to avoid causing unnecessary churn in required imports.
Resolves rdar://132525152.
Control enforcement of member import visibility requirements via a new option,
instead of piggy-backing on the existing IgnoreAccessControl option. Adopt the
option when doing fallback lookups for unviable members so that the compiler
can diagnose the reason that a member is inaccessible more reliably.
Previously, with MemberImportVisibility enabled decls with the package access
level could be mis-diagnosed as inaccessible due to their access level when
really they were inaccessible due to a missing import.
Resolves rdar://131501862.
In Swift 5.10 if you wrote `extension Foo {}` for some protocol Foo,
the extension would always re-use the generic signature of Foo, which
is <Self where Self: Foo>. In Swift 6 this no longer works because Foo
might be ~Copyable, in which case `extension Foo {}` adds default
requirements, so we changed GenericSignatureRequest to just always
build a new signature if we're given an extension.
However, to avoid a request cycle with a code example that really should
have never worked at all, I'm re-introducing the hack for re-using the
signature.
Fixes rdar://problem/129540617.
We have two "levels" of name lookup, and the more primitive level is
used by name lookup itself to avoid certain cycles. For example,
extension binding, resolution of inheritance clauses, etc.
One interesting case is that a protocol extension can impose additional
requiremnts on `Self`, and members of the right-hand side type are
visible to unqualified lookup.
The right-hand side of a `Self` requirement in this case is always a
protocol type or class type canonically, but it might be written to
refer to a protocol type alias.
Before some changes for noncopyable generics, the primitive name
lookup mechanism, implemented in directReferencesForTypeRepr() and
such, would check if the TypeRepr had already been resolved by
resolveType(). If so, it would immediately return the decl.
This masked an issue, where the right-hand side of a `Self` requirement
was resolved in the parent DeclContext. A more subtle rule is needed;
for a protocol extension, we must resolve the right-hand side in the
protocol, but disregard the protocol extension's `Self` requirements,
because doing so would recursively trigger the same lookup again.
Fixes rdar://problem/124498054.
In rdar://123649082, a project failed to build because of the lazy import-as-member loading changes in #71320. That project was configured in a way that broke modularization and the correct solution is to fix it, but out of an abundance of caution, add a `-disable-named-lazy-import-as-member-loading` frontend flag in case a project needs to temporarily restore the old behavior.
As a bonus, this lets us write a test to verify that lazy import-as-member loading has positive performance impact.
If an extension isn't imported either directly or via a transitive
(`@_exported`) import, its members should not be visible to name
lookup. Implement this behavior behind the experimental flag
ExtensionImportVisibility.
Previously, if a request R evaluated itself N times, we would emit N
"circular reference" diagnostics. These add no value, so instead let's
cache the user-provided default value on the first circular evaluation.
This changes things slightly so that instead of returning an
llvm::Expected<Request::OutputType>, various evaluator methods take
a callback which can produce the default value.
The existing evaluateOrDefault() interface is unchanged, and a new
evaluateOrFatal() entry point replaces
llvm::cantFail(ctx.evaluator(...)).
Direct callers of the evaluator's operator() were updated to pass in
the callback. The benefit of the callback over evaluateOrDefault() is
that if the default value is expensive to constuct, like a dummy
generic signature, we will only construct it in the case where a
cycle actually happened, otherwise we just delete the callback.
(cherry picked from commit b8fcf1c709efa6cd28e1217bd0efe876f7c0d2b7)
Both `try?` and `try!` are catch nodes, because they catch an error
thrown in their subexpression and handle it. Introduce an ASTScope for
all `try/try?/try1` expressions so we can find them, and model them as
catch nodes.
Fixes rdar://119216455.
The review of SE-0395 is down to small details at this point that won't
affect the overall shape of the API much. Rename the model in
anticipation of that.