- Introduce a generic requirements opening function for type resolution,
which is used by the constraint system in cases where we need to
impose requirements on opened type variables.
- Refactor `replaceInferableTypesWithTypeVars` to use this function
when opening generic types that contain either placeholder or unbound
generic types.
Together these changes ensure that we don't drop generic requirements
when an unbound generic or placeholder type is used as a generic
argument.
Requirement opening relies on being able to query the opened type to
allow requirement fix coalescing to work. Record the opened type before
we open requirements to ensure we don't duplicate requirement fixes on
the base type with requirement fixes for the member.
https://github.com/swiftlang/swift/pull/72659 turned out to have some
source compatibility fallout that we need to fix. Instead of introducing
yet another brittle compatibility hack, stop emitting errors about a
missing `any` altogether until a future language mode.
Besides resolving the compatibility issue, this will encourage
developers to adopt any sooner and grant us ample time to gracefully
address any remaining bugs before the source compatibility burden
resurfaces.
A subsequent commit adds a diagnostic group that will allow users to
escalate these warnings to errors with `-Werror ExistentialAny`.
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
We don't support nested types in methods of generic types, so the new
error popping up about `A` being noncopyable is not too surprising,
but also not the point of this test anyway.
The original bug was a crash-on-invalid with a missing '}', but it
actually exposed a bug with nested protocols (SE-0404) and another
long-time bug.
- Whatever we do, we should skip this for protocols because their 'Self'
parameter is not bound from context.
- getTrailingWhereClause() is not the right proxy for "has a generic
signature different than its parent", in particular it doesn't
round-trip through serialization. Instead, just compare generic
signatures for pointer equality in the early return check.
The second change is source-breaking because it was possible to
write a nested type with a `where` clause and use it contradicting
its requirements across a module boundary.
Fixes rdar://113103854.
Code like that is usually indicative of programmer error, and does not
round-trip through module interface files since there is no source
syntax to refer to an outer generic parameter.
For source compatibility this is a warning, but becomes an error with
-swift-version 6.
Fixes rdar://problem/108385980 and https://github.com/apple/swift/issues/62767.
The previous warning "must be explicitly marked as 'any'" isn't clear if
you don't already know the feature, this new phrasing should make it
clearer by including the correct spelling of the type as an example.
Fixes rdar://90384448
If you have a class with an (invalid) protocol nested inside:
class OuterGenericClass<T, U> {
protocol InnerProtocol : OuterGenericClass {}
}
The reference to 'OuterGenericClass' in the protocol's inheritance
clause is not "in context", and should not have inferred generic
arguments <T, U>, because the protocol does not inherit the generic
arguments of the outer scope.
Previously, this would trigger an assertion in the requirement
machine, because the generic parameter τ_0_1 is not a valid generic
parameter in the protocol's generic signature.
The following regression test added for this feature is not passing:
Swift(linux-x86_64) :: decl/protocol/protocols_with_self_or_assoc_reqs_executable.swift
with a compiler crash happening during SILFunctionTransform "Devirtualizer".
Reverting to unblock CI.
This reverts commit f96057e260, reversing
changes made to 3fc18f3603.
Use the FullyQualified<Type> abstraction from the prior commit plus DescriptiveDeclKind to give a bit more information when issuing a missing member type diagnostic during type resolution.
There were two problems here:
- isUnsupportedMemberTypeReference() checked if the immediate parent type was
an unbound generic type, but did not check for the parent of the parent, etc.
- The caller of isUnsupportedMemberTypeReference() had to re-check the
various invalid conditions to determine what diagnostic to emit, and if
none of those conditions matched it would just return an ErrorType without
emitting a diagnostic.
Fix both of these by having isUnsupportedMemberTypeReference() return an
enum indicating what went wrong, and handle more cases.
Fixes <rdar://problem/67292528>.
Although such functionality is not yet supported we have to
mirror AST lookup and add such members into results, otherwise
there is a risk of inner/outer results mismatch.
Witness matching is a source of a lot of ad-hoc cycles, and mixes the
logic that performs resolution, caching, validation, and cycle detection into one
place. To make matters worse, some checkers kick off other checks in
order to cache work for further declarations, and access an internal
cache on their subject conformance for many requirements at once, or
sometimes just one requirement.
None of this fits into the request evaluator's central view of the
caching. This is further evidenced by the fact that if you attempt to
move the caching step into the evaluator, it overcaches the same
witness and trips asserts.
As a start, define requests for the resolution steps, and flush some
hacks around forcing witness resolution. The caching logic is mostly
untouched (the requests don't actually cache anything), but some cycle
breaking is now handled in the evaluator itself. Once witness matching
has been refactored to cache with the evaluator, all of these hacks can
go away.
My urge to destroy the LazyResolver outweighs the compromises here.
In preparation for checkEnumRawValues being turned into a request, move the common diagnostics to the decl checker so they're always emitted at the right time.
Computing the generic signature changes the way that cycles appear in the compiler. For now, break these cycles. We should investigate each place where hasComputedGenericSignature() is used in service of breaking cycles. See rdar://55263708
When there's a module with the same name as a type in a
different module, lookup will look into the type, not the module, when
resolving members. Until that behavior is fixed, add a note showing what
lookup was trying to look into, to make the behavior more clear.
Helps rdar://54770139
Previously in situations like:
```swift
protocol P {}
struct S<T: P> {
var value: T
}
_ = S(value: 42)
```
Diagnostic has reported a problem as related to "reference" to `init`
but the failing generic type requirement belongs to `S`, so a
better diagnostic in such case should mention `generic struct S`.
Introduce a fix to detect and diagnose situations when omitted
generic arguments couldn't be deduced by the solver based on
the enclosing context.
Example:
```swift
struct S<T> {
}
_ = S() // There is not enough context to deduce `T`
```
Resolves: rdar://problem/51203824
While computing a type of member via `getTypeOfMemberReference`
let's delay opening generic requirements associated with function
type until after self constraint has been created, that would give
a chance for contextual types to get propagated and make mismatch
originated in generic requirements much easier to diagnose.
Consider following example:
```swift
struct S<T> {}
extension S where T == Int {
func foo() {}
}
func test(_ s: S<String>) {
s.foo()
}
```
`foo` would get opened as `(S<$T>) -> () -> Void` and contextual `self`
type is going to be `S<String>`, so applying that before generic requirement
`$T == Int` would make sure that `$T` gets bound to a contextual
type of `String` and later fails requirement constraint `$T == Int`.
This is much easier to diagnose comparing to `$T` being bound to
`Int` right away due to same-type generic requirement and then
failing an attempt to convert `S<String>` to `S<Int>` while simplifying
self constraint.
Resolves: rdar://problem/46427500
Resolves: rdar://problem/34770265
* Make Self available to instance member functions (SE-0068?)
* Works for value types and static functions.
* Further experiments with TypeExpr
* Move Self processing off diagnostic path
* diagnostic instead of assertion fail
* TypeExpr of DynamicSelfType now working.
* Update tests for availability of Self
* Cast to Self fixed!
* Self not available as type in classes except for return type
* Could it be this simple?
* Nearly there
* Fix function decls using Self inside methods.
* Fix validation-test/compiler_crashers_2_fixed/0164-sr7989.swift
* Fix of ./validation-test/compiler_crashers_2_fixed/0179-rdar44963974.swift
* "Un-fix" validation-test/compiler_crashers_2_fixed/0164-sr7989.swift
* CHANGELOG entry
* Update CHANGELOG.md
Co-Authored-By: johnno1962 <github@johnholdsworth.com>
* Update CHANGELOG.md
Try to fix constraint system in a way where member
reference is going to be defined in terms of its use,
which makes it seem like parameters match arguments
exactly. Such helps to produce solutions and diagnose
failures related to missing members precisely.
These changes would be further extended to diagnose use
of unavailable members and other structural member failures.
Resolves: rdar://problem/34583132
Resolves: rdar://problem/36989788
Resolved: rdar://problem/39586166
Resolves: rdar://problem/40537782
Resolves: rdar://problem/46211109
We allow this sort of thing:
struct Generic<T> {}
typealias Alias = Generic
...
Alias<Int>
However we have to be sure to ban this if the typealias is itself generic, ie
typealias Alias<T> = Generic
Otherwise we will crash.