We now introduce a TypeRefinementContext for the fallthrough branch of a require/else
statement that continues until the end of the BraceStmt that contains the RequireStmt. The
body of the else is checked in the context that contains the RequireStmt.
This enables availability checking with early return:
require #available(iOS 8.0, *) else { return }
Swift SVN r28113
Loosen restrictions on where #available() can appear in IfStmt guards and refine the
context for guard StmtConditionElements following an availability check.
This enables #available() to be combined with if let optional binding:
if #available(iOS 8.0, *),
let x = someIOS8API() {
// Do more iOS 8 stuff
}
and
if let x = someIOS7API() where #available(iOS 8.0, *),
let y = someIOS8API() {
// Do more iOS 8 stuff
}
Swift SVN r28096
Change the syntax of availability queries from #available(iOS >= 8.0, OSX >= 10.10, *) to
This change reflects the fact that now that we spell the query '#available()' rather than
'#os()', the specification is about availability of the APIs introduced in a particular OS
release rather than an explicit range of OS versions on which the developer expects the
code to run.
There is a Fix-It to remove '>=' to ease adopting the new syntax.
Swift SVN r28025
Change how MemberRefExpr and DynamicMemberRefExpr calculate their starting locations so
that even if their base expression is implicit, they will use its starting location if
that location is valid rather than falling back to the start of the name of the member.
Without this change, the Fix-It to suggest wrapping a nested member reference (where the
base is an implicit LoadExpr) in 'if #available(...)' would be inserted in the middle of
the expression.
rdar://problem/20662960
Swift SVN r27799
To be safe, protocol witnesses need to be as available as their requirements.
Otherwise, the programmer could access an unavailable declaration by upcasting
to the protocol type and accessing the declaration via its requirement.
Prior to this commit, we enforced safety by requiring that the annotated
available range of a requirement must be completely contained within the
annotated available range of the witness.
However, there are cases where this requirement is too restrictive. Suppose
there is some super class Super with an availability-restricted method f():
class Super {
@availability(iOS, introduced=6.0)
void func f() { ... }
}
Further, suppose there is a protocol HasF with unrestricted availability:
protocol HasF {
void func f()
}
and then a limited-availability class Sub extends Super and declares a
conformance to HasF:
@availability(iOS, introduced=8.0)
class Sub: Super, HasF {
}
Sub does conform to HasF: the witness for HasF's f() requirement is Super's f().
But Super's f() is less available (iOS 6 and up) than HasF's f() requires
(all versions) and so--prior to this commit--the compiler would emit
an error.
This error is too conservative. The conforming type, Sub,
is only available on iOS 8.0 and later. And, given an environment of iOS 8.0
and later, the availability of the requirement and the witness is the same, so
the conformance is safe.
This false alarm arises in UIKit, where Super is UIView, HasF
is UIGestureRecognizerDelegate, and f() is gestureRecognizerShouldBegin().
The fix is to change the safety requirement for protocol witnesses:
we now require that the intersection of the availabilities of the conforming
type and the protocol requirement is fully contained in the intersection of the
availabilities of the conforming type and the witness. It does not matter if
the containment does not hold for versions on which the conforming type is not
available.
rdar://problem/20693144
Swift SVN r27712
Update the Fix-It thats suggests adding a #available() check to include the
wildcard query '*', which is now required. We were omitting it before, which
meant that after applying this Fix-It the developer would get a second Fix-It
to add the '*'.
rdar://problem/20601569
Swift SVN r27514
Suppress API availability diagnostics about protocol conformances when the
-disable-availability-checking frontend flag is passed. We weren't
checking the flag before, so there was no way to disable this diagnostic.
I've added a test to make sure this flag is honored. We can remove the test when
we remove the flag, which is temporary.
Swift SVN r27439
Enable checking for uses of potentially unavailable APIs. There is
a frontend option to disable it: -disable-availability-checking.
This commit updates the SDK overlays with @availability() annotations for the
declarations where the overlay refers to potentially unavailable APIs. It also changes
several tests that refer to potentially unavailable APIs to use either #available()
or @availability annotations.
Swift SVN r27272
Make sure that a witness declaration is at least as available as
the protocol requirement declaration. This is analogous to requiring that an
override is at least as available as the base declaration.
We don’t use the RequirementMatch machinery to mark a candidate as unsafe but
rather let the witness be chosen and then diagnose for potential unavailability.
That is, potential unavailability will not affect the search for a candidate
witness to a requirement. This is less expressive (users cannot write a protocol
that selects an available implementation) but is more predictable.
Swift SVN r27256
For now, disallow potential unavailability on stored properties. We will
eventually want to support this. Unfortunately, doing so will require changes to
definite initialization and (probably) deinitialization.
This is the same as the reverted r27216 except that it does not suggest a FixIt
to make the property lazy.
Swift SVN r27223
For now, disallow potential unavailability on stored properties. We will
eventually want to support this. Unfortunately, doing so will require changes to
definite initialization and (probably) deinitialization.
We can safely support potential unavailability on lazily initialized
properties (and statics), so suggest a Fix-It that adds a lazy attribute when
the property declaration allows for it.
Swift SVN r27216
In source files that are in script mode, global variable initialization
expressions are eagerly executed. For this reason, disallow @availability
attributes having 'introduced=' on script-mode globals.
I had to rejigger a fair number of potential unavailability tests because they
weren't written with this distinction in mind.
Swift SVN r27137
Synthesize implicit @availability attributes to make sure that a synthesized
materializeForSet accessor is available enough to access the underlying storage and its
getter and setter.
These synthesized attributes could trigger redundant diagnostics when a subclass gives
overriding getters or setters non-contravariant availability. We detect when this
happens and suppress the redundant diagnostics.
This commit also improves availability diagnostics in synthesized code. We now respect
synthesized @availability annotations on containing DeclContexts when determining the
potential OS versions that could be executed at invalid SourceLocations.
Swift SVN r27002
The API review list found it confusing that if #os() and #if os() looked so similar, so
change the availability checking query to be spelled #available:
if #available(iOS >= 9.0, *) {
...
}
Swift SVN r26995
On platforms that are not explicitly mentioned in the #os() guard, this new '*'
availability check generates a version comparison against the minimum deployment target.
This construct, based on feedback from API review, is designed to ease porting
to new platforms. Because new platforms typically branch from
existing platforms, the wildcard allows an API availability check to do the "right"
thing (executing the guarded branch accessing newer APIs) on the new platform without
requiring a modification to every availability guard in the program.
So, if the programmer writes:
if #os(OSX >= 10.10, *) {
. . .
}
and then ports the code to iOS, the body will execute.
We still do compile-time availability checking with '*', so the compiler will
emit errors for references to potentially unavailable symbols in the body when compiled
for iOS.
We require a '*' clause on all #os() guards to force developers to
"future proof" their availability checks against the introduction of new a platform.
Swift SVN r26988
Change availability Fix-It notes to use a DescriptiveDeclKind so that the notes are
more precise in their description of where an availability attribute will be added.
So, for example, the note will now say "add @availability attribute to enclosing class"
instead of "add @availability attribute to enclosing type".
In these Fix-Its, I have special-cased the descriptive kind for PatternBindingDecls to
instead use the description for an associated VarDecl to avoid describing property
declarations as "pattern bindings" to the user.
Swift SVN r26420
The commit fixes availability Fix-Its on enum elements to suggest a new availability
attribute on the enum case (which is where attributes live in concrete syntax) rather than
on the enum element (which is where they are attached in the abstract syntax tree).
Swift SVN r26401
Minor tweaks to availability diagnostic text based on feedback from Chris, Ted, and Doug.
This changees "'foo' is only available on OS X version 10.10 or greater" to
"'foo' is only available on OS X 10.10 or newer".
This change also updates the deprecation and obsoleted diagnostics to be consistent with
the new text.
Swift SVN r26344
We now suggest up to three Fix-Its for each reference to a potentially
unavailable symbol: one to wrap the reference in an if #os(...) { ... }
guard (if possible), one to add an @availability attribute to an enclosing
property or method (if possible), and one to add an @availability attribute
to an enclosing class/struct/extension, etc. or global function.
The goal here is not to infer the "best" Fix-It but rather to ensure
discoverability of #os() and @availability attributes. We want the user, when
faced with an availability diagnostic, to be aware of the tools in her toolbox
to deal with it.
This is still missing QoI improvements, including Fix-Its to update
existing @availability attributes and more precise wording in diagnostics
(e.g, "initializer" instead of function, "class" instead of "type"). These
improvements will come in later commits.
Swift SVN r26073
At Jordan's request, add a test to ensure that we emit an error when a declaration
inside an extension is more available than the extension itself. Also change a
getContextKind() comparison + cast<> to a dyn_cast<>.
Swift SVN r25592
This commit allows @availability attributes on extensions.
Unlike other declarations, extensions can be used without referring to them
by name (they don't have one) in the source. For this reason, when checking
the available version range of a declaration we also need to check to see if it is
immediately contained in an extension and use the extension's availability if
the declaration does not have an explicit @availability attribute itself.
This commit also moves building the primary file type refinement context hierarchy
in performTypeChecking() to before we resolve extensions. Resolving extensions checks for
availability of the extended declaration, so the TRC for the extension must be constructed
before then.
Swift SVN r25589
This commit removes an unnecessary check that ensured that inferred type
parameter actuals are available. This check is unnecessary because the
declaration for any inferred actual type parameter (i.e., a generic type
argument at the callsite) must be referred to in an enclosing type refinement
context. If the inferred type is not available, this reference will cause a
diagnostic to be emitted, so we don't need to emit another diagnostic for the
inferred actual. Further, this diagnostic was potentially confusing because the
point at which we emitted the diagnostic did not directly mention the type
name (because it was inferred).
This commit also beefs up testing of diagnostics for potentially unavailable
type parameters.
Swift SVN r25540
This commit validates @availability() attribute version ranges to ensure that
a declaration is not more available than its lexically containing scope. To do so,
we find the inner-most declaration containing an @availability attribute that itself
has an @availability attribute and check that first attribute's available
version range is contained in the enclosing declaration's available range. If not,
we emit a diagnostic.
This commit removes a FIXME for checking @availability and overrides. It appears that
the FIXME is a copy/paste to/from AttributeOverrideChecker, where it still resides.
Swift SVN r25453
With this commit, availability attributes can now be placed on enum elements. We
emit an error (protected by the -enable-experimental-availability-checking flag) for
references to potentially unavailable enum cases. We do *not* emit an error when the
programmer pattern matches (i.e., with switch) on a potentially unavailable case.
This commit does not import availability attributes from clang. I will add support for
this in a later commit.
Swift SVN r24929
This commit adds checking for accesses of potentially unavailable getters and setters.
When walking an expression to check availability, AvailabilityWalker now keeps track of
the context for when it encounters a MemberRefExpr. This context be either
(1) the next encountered member reference could cause the member's getter to be called
(e.g., the member ref is for a read of the property); (2) the member's setter could be
called (e.g., the member ref is the left-hand-side of an assignment); or (3) the member
ref generates the lvalue for for an InOutExpr (&) -- in which case we have to assume both
the getter and the setter could be called. These diagnostics are protected by the
-enable-experimental-availability-checking flag.
This commit does not import separate getter and setter availability from Objective-C; that
is coming in a future commit.
Swift SVN r24870
Most tests were using %swift or similar substitutions, which did not
include the target triple and SDK. The driver was defaulting to the
host OS. Thus, we could not run the tests when the standard library was
not built for OS X.
Swift SVN r24504
Previously the "as" keyword could either represent coercion or or forced
downcasting. This change separates the two notions. "as" now only means
type conversion, while the new "as!" operator is used to perform forced
downcasting. If a program uses "as" where "as!" is called for, we emit a
diagnostic and fixit.
Internally, this change removes the UnresolvedCheckedCastExpr class, in
favor of directly instantiating CoerceExpr when parsing the "as"
operator, and ForcedCheckedCastExpr when parsing the "as!" operator.
Swift SVN r24253
This commit updates diagnostic reporting for #os() checks that will always pass.
We now indicate whether the reason the check will always pass is because of the
minimum deployment target or is because of an enclosing scope. In the latter
case, we emit a note indicating the location of the enclosing scope.
Swift SVN r22729
We restrict #os(...) to only the guard condition of if statements. We may want
to loosen this restriction in the future (to, e.g., IfExprs) -- but, in general,
we don't want #os() to appear where static analysis cannot easily determine
its effect.
Swift SVN r22720
This commit changes building of type refinement contexts for accessor functions
to use the type refinement context of its associated storage as a parent
rather than its lexically-enclosing context. With this change, we now
associate new child contexts inside property accessors with the TRC of the
property rather than the TRC of the container of the anonymous function created
for the accessor. This commit also adds a dump() debug method to
TypeRefinementContext.
Swift SVN r22718
Make method/property availability contravariant: the available range of an
override must contain the available range of the overriden declaration.
Swift SVN r22682
This commit adds checking of declarations with potentially unavailable types to
the existing checking for explicitly unavailable types. At the moment, these
two checking mechanisms are separate -- I will unify them in a future commit.
This commit removes the TypeExpr-based checking added in r22651; such checks
are now superfluous.
Swift SVN r22679
This commit adds availability checking for references to classes in Sema. We
now emit a diagnostic when a potentially unavailable class is referenced
in an expression, either directly (via a TypeExpr) or as the result of being
substituted as a replacement type in a call to a generic function. This
latter check is needed at the callsite because the callee may use its
formal type parameter to get at the metadata for the type.
This commit does not check declarations of variables, etc., with unavailable
types -- this will come in a later patch.
Swift SVN r22651
This commit adds availability checking for properties to Sema. When
EnableExperimentalAvailabilityChecking is enabled, we now emit a diagnostic
when a potentially unavailable property is accessed. To support this, we
now build type refinement contexts for most ValueDecls.
Swift SVN r22622
This patch adds diagnostics for initializers that are potentially unavailable.
It does not treat such initializers as optionals, even when
EnableExperimentalUnavailableAsOptional is true -- there is some tricky
interaction with failable initializers that still needs to be worked out.
Swift SVN r22548
This commit modifies Sema to add type checking for potentially unavailable
method references. We now record the reason for method unavailability when
recording a potential overload choice during member constraint simplification
and either diagnose or lift to an optional type during CSApply. This commit also
generalizes UnavailableToOptionalExpr to take an arbitrary subexpression.
This commit does not address potentially unavailable properties, initializers,
or dynamic member references.
Swift SVN r22508
This commit also factors out some common checking and diagnostic code; it
additionally moves diagnostic emission for unavailable references from CSGen to
CSApply.
Swift SVN r22447
This commit adds tests to demonstrate that availability checking works,
at the Sema level, for global functions. SILGen for potentially unavailable
global functions is not yet implemented.
Swift SVN r22406
This commit adds tracking of the reason a declaration reference is potentially
unavailable to the UnavailableToOptionalExpr AST node and to OverloadChoice. We
will use this reason during SILGen to emit the appropriate run-time check and
during typechecking to provide more helpful diagnostics.
To keep OverloadChoice as small as possible, we encode the reason as an index
into a vector of reasons stored in a given instance of ConstraintSystem (this is
the same approach that Fix takes).
This commit adds Sema/OverloadChoice.cpp (for the parts of OverloadChoice that
now rely on ConstraintSystem) and AST/Availability.h (to bring in
availability-related structures without TypeRefinementContext).
Swift SVN r22377
This patch adds construction of type refinement contexts for the Then branch of
availability queries and adds diagnostics for ill-formed queries. For the
moment, we do not refine for the Else branch because the version range lattice
is not precise enough to do so helpfully.
This patch does not properly handle availability queries involving application
extension platforms (noted with a FIXME). I will add support for these platforms
in a future commit.
Swift SVN r22165
This patch adds the beginning of building the type refinement context tree for
availability checking in Sema, guarded by by the
-enable-experimental-availability-checking option. This tree parallels the AST
but is much more sparse: we introduce a new TypeRefinementContext only when
needed. Each context refines the range of potential OS versions that could be
encountered at run time. For the moment, we only refine contexts for function
bodies. I will add refinement contexts for #os(...) in a later commit.
The AST is not directly connected to the TRC tree except at the SourceFile
level; when type checking, we use source locations to look up the TRC
corresponding to an AST element. For the moment, we emit a diagnostic when the
programmer references a potentially unavailable declaration. We will later
change this to treat the declaration as if it had optional type.
Swift SVN r22145