This check had two problems. First, it would assert upon encountering
a layout requirement, due to an unimplemented code path.
A more fundamental issue is that the logic wasn't fully sound, because
it would miss certain cases, for example:
protocol P {
associatedtype A
func run<B: Equatable>(_: B) where B == Self.A
}
Here, the reduced type of `Self.A` is `B`, and at first glance, the
requirement `B: Equatable` appears to be fine. However, this
is actually a new requirement on `Self`, and the protocol be rejected.
Now that we can change the reduction order by assigning weights to
generic parameters, this check can be implemented in a better way,
by building a new generic signature first, where all generic
parameters introduced by the protocol method, like 'B' above, are
assigned a non-zero weight.
With this reduction order, any type that is equivalent to
a member type of `Self` will have a reduced type rooted in `Self`,
at which point the previous syntactic check becomes sound.
Since this may cause us to reject code we accepted previously,
the type checker now performs the check once: first on the original
signature, which may miss certain cases, and then again on the new
signature built with the weighted reduction order.
If the first check fails, we diagnose an error. If the second
check fails, we only diagnose a warning.
However, this warning will become an error soon, and it really
can cause compiler crashes and miscompiles to have a malformed
protocol like this.
Fixes rdar://116938972.
`TypeSimplifier` may not eliminate type variables from e.g the
pattern types of pattern expansion types since they can remain
unresolved due to e.g having a placeholder count type. Make sure we
eliminate any remaining type variables along with the placeholders.
There's probably a more principled fix here, but this is a quick and
low risk fix we can hopefully take for 6.2.
rdar://154954995
If we fail to resolve the value type for a value generic parameter,
previously we would have returned a null Type, causing crashes
downstream. Instead, return an ErrorType, leaving a null Type for
cases where the generic parameter isn't a value generic at all.
rdar://154856417
Resolves rdar://152598492
Consider the following Swift, adapted from a real-world framework:
```swift
@available(macOS 10.8, *)
@_originallyDefinedIn(module: "another", macOS 11.0)
public struct SimpleStruct {}
@available(macOS 12.0, iOS 13.0, *)
public extension SimpleStruct {
struct InnerStruct {}
}
```
In this scenario, `SimpleStruct` was originally in a module called
`another`, but was migrated to this module around the time of macOS
11.0. Since then, the module was ported to iOS and gained a nested type
`SimpleStruct.InnerStruct`. When mangling USRs for this nested type, the
result differs depending on whether we're targeting macOS or iOS.
They're mostly the same, but the macOS build yields a USR with an `AAE`
infix, designating that the `InnerStruct` was defined in an extension
from a module with the name of the base module. On iOS, this infix does
not exist.
The reason this is happening is because of the implementation of
`getAlternateModuleName` checking the availability spec in the
`@_originallyDefinedIn` attribute against the currently active target.
If the target matches the spec, then the alternate module name is
reported, otherwise the real module name is. Since the iOS build reports
the real module name, the mangling code doesn't bother including the
extension-context infix, instead just opting to include the parent
type's name and moving on.
This PR routes around this issue by passing the
`RespectOriginallyDefinedIn` variable to the
`ExtensionDecl::isInSameDefiningModule` method, and using that to skip
the alternate module name entirely. It also sets
`RespectOriginallyDefinedIn` to `false` in more places when mangling
USRs, but i'm not 100% confident that it was all necessary. The goal was
to make USRs more consistent across platforms, regardless of the
surrounding context.
Diagnostics can outlive the ConstraintSystem itself if we have a
diagnostic transaction for e.g `typeCheckParameterDefault`, make sure
we don't try to use a solver-allocated type as an argument.
Adjust isolation checking to handle misused `isolated` attribute
and let attribute checker property diagnose it.
Resolves: rdar://148076903
Resolves: https://github.com/swiftlang/swift/issues/80363
Infer result type of a subscript with Array or Dictionary base type
if argument type matches the key type exactly or it's a supported
literal type.
This helps to maintain the existing behavior without having to resort
to "favored type" computation.
When matching candidate like `[Int]` against `Array<Element>`
we need to conservatively assume that if the nominals match
the argument is a viable exact match because otherwise it's
possible to skip some of the valid matches when other overload
choice have generic parameters at the same parameter position.
The problem this is trying to solve is eager selection of operators
over unsupported disjunctions, when matching operators let's take
speculative information into account because it helps to make better
choices in this case.
The test was slow with hacks but now it's much faster - takes about
63k scopes to solve, it could be improved by introducing new overloads
of prefix `-` to stdlib.
Some of the disjunctions are not supported by the optimizers but
could still be a better choice than an operator. Using a non-score
based preference mechanism first allows us to make sure that
operator disjunctions are not selected too eagerly in some situations
when i.e. a member (supported or not) could be a better choice.
`isPreferable` currently targets only operators in result builder
contexts but it could be expanded to more uses in the future.
New ranking + selection algorithm suffered from over-eagerly selecting
operator disjunctions vs. unsupported non-operator ones even if the
ranking was based purely on literal candidates.
This change introduces a notion of a speculative candidate - one which
has a type inferred from a literal or an initializer call that has
failable overloads and/or implicit conversions (i.e. Double/CGFloat).
`determineBestChoicesInContext` would reset the score of an operator
disjunction which was computed based on speculative candidates alone
but would preserve favoring information. This way selection algorithm
would not be skewed towards operators and at the same time if there
is no no choice by to select one we'd still have favoring information
available which is important for operator chains that consist purely
of literals.
If there are no-same type requirements and parameters use
either concrete types or generic parameter types directly,
the optimizer should be able to handle ranking. Currently
candidate arguments are considered in isolation which makes
it impossible to deal with same-type requirements and
complex generic signatures.
rdar://153681688
Instead fo counting the actual conformances, the logic took the size of the bit field, i.e. used the highest set bit, so when a type had a conditional conformance only on ~Escapable, but not on ~Copyable, it would still add 2 placeholders, but only fill one.