the regressions that r31105 introduced in the validation tests, as well as fixing a number
of other validation tests as well.
Introduce a new UnresolvedType to the type system, and have CSDiags start to use it
as a way to get more type information out of incorrect subexpressions. UnresolvedType
generally just propagates around the type system like a type variable:
- it magically conforms to all protocols
- it CSGens as an unconstrained type variable.
- it ASTPrints as _, just like a type variable.
The major difference is that UnresolvedType can be used outside the context of a
ConstraintSystem, which is useful for CSGen since it sets up several of them to
diagnose subexpressions w.r.t. their types.
For now, our use of this is extremely limited: when a closureexpr has no contextual
type available and its parameters are invalid, we wipe them out with UnresolvedType
(instead of the previous nulltype dance) to get ambiguities later on.
We also introduce a new FreeTypeVariableBinding::UnresolvedType approach for
constraint solving (and use this only in one place in CSDiags so far, to resolve
the callee of a CallExpr) which solves a system and rewrites any leftover type
variables as UnresolvedTypes. This allows us to get more precise information out,
for example, diagnosing:
func r22162441(lines: [String]) {
lines.map { line in line.fooBar() }
}
with: value of type 'String' has no member 'fooBar'
instead of: type of expression is ambiguous without more context
This improves a number of other diagnostics as well, but is just the infrastructural
stepping stone for greater things.
Swift SVN r31130
as a way to get more type information out of incorrect subexpressions. UnresolvedType
generally just propagates around the type system like a type variable:
- it magically conforms to all protocols
- it CSGens as an unconstrained type variable.
- it ASTPrints as _, just like a type variable.
The major difference is that UnresolvedType can be used outside the context of a
ConstraintSystem, which is useful for CSGen since it sets up several of them to
diagnose subexpressions w.r.t. their types.
For now, our use of this is extremely limited: when a closureexpr has no contextual
type available and its parameters are invalid, we wipe them out with UnresolvedType
(instead of the previous nulltype dance) to get ambiguities later on.
We also introduce a new FreeTypeVariableBinding::UnresolvedType approach for
constraint solving (and use this only in one place in CSDiags so far, to resolve
the callee of a CallExpr) which solves a system and rewrites any leftover type
variables as UnresolvedTypes. This allows us to get more precise information out,
for example, diagnosing:
func r22162441(lines: [String]) {
lines.map { line in line.fooBar() }
}
with: value of type 'String' has no member 'fooBar'
instead of: type of expression is ambiguous without more context
This improves a number of other diagnostics as well, but is just the infrastructural
stepping stone for greater things.
Swift SVN r31105
diagnoseGeneralFailure to be named diagnoseConstraintFailure and change how
it works:
Now it ranks unresolved constraints in the system based on kind (e.g. whether
they are favored, member constraints ahead of conversion constraints, etc) and
then tries to emit a diagnostic for each failure kind one after another.
This means that if there are multiple failed conversion constraints, but one
is obviously satisfiable, that we continue on to diagnose the next one. This
clears up a swath of embarassing diagnostics and refixes:
<rdar://problem/19658691> QoI: Incorrect diagnostic for calling nonexistent members on literals
Swift SVN r31046
and diagnoseGeneralConversionFailure(). The previous approach of trying
to dig into anchors would often lead to complaining about types at
different levels in the same diagnostic, and the complexity of the former
code isn't needed now that other changes have landed.
Swift SVN r31036
using it to improve closure diagnostics by inferring the types of otherwise
untyped closure paramdecls from this context information. This
resolves:
<rdar://problem/20371273> Type errors inside anonymous functions don't provide enough information
producing
error: binary operator '==' cannot be applied to operands of type 'Int' and 'UInt'
note: overloads for '==' exist with these partially matching parameter lists: (UInt, UInt), (Int, Int)
and:
<rdar://problem/20978044> QoI: Poor diagnostic when using an incorrect tuple element in a closure
producing:
error: value of tuple type '(Int, Int)' has no member '2'
and probably a lot more. We're still limited from getting things like "foo.map {...}" because
we're not doing type subsitutions from the base into the protocol extension member.
Swift SVN r30971
argument. For now we start with some of the most simple cases: single argument
calls. This dramatically improves the QoI for error messages in argument lists,
typically turning a error+note combo into a single specific error message.
Some minor improvements coming (and also generalizing this to n-ary calls), but it
is nice that all the infrastructure is starting to come together...
Swift SVN r30905
https://twitter.com/practicalswift/status/625429628107255808?refsrc=email&s=11
all compile without crashing, other than "()=()", which is tracked by:
<rdar://problem/21886435> Swift compiler crashes on "()=()"
This one crashes because "()" isn't being type checked as an lvalue. If someone
feels inspired to fix this, it is our shortest known compiler crash.
Swift SVN r30735
"unavoidable failure" path, along with Failure::DoesNotHaveNonMutatingMember and
just doing some basic disambiguation in CSDiags.
This provides some benefits:
- Allows us to plug in much more specific diagnostics for the existing "only has
mutating members" diagnostic, including producing notes for why the base expr
isn't mutable (see e.g. test/Sema/immutability.swift diffs).
- Corrects issues where we'd drop full decl name info for selector references.
- Wordsmiths diagnostics to not complain about "values of type Foo.Type" instead
complaining about "type Foo"
- Where before we would diagnose all failures with "has no member named", we now
distinguish between when there is no member, and when you can't use it. When you
can't use it, you get a vauge "cannot use it" diagnostic, but...
- This provides an infrastructure for diagnosing other kinds of problems (e.g.
trying to use a private member or a static member from an instance).
- Improves a number of cases where failed type member constraints would produce uglier
diagnostics than a different constraint failure would.
- Resolves a number of rdars, e.g. (and probably others):
<rdar://problem/20294245> QoI: Error message mentions value rather than key for subscript
Swift SVN r30715
get the same wording, fixing <rdar://problem/21964599> Different diagnostics for the same issue
While I'm in the area, remove some dead code.
Swift SVN r30713
which we have a contextual type that was the failure reason. These are a bit
longer but also more explicit than the previous diagnostics.
Swift SVN r30669
- Improve handling of if_expr in a couple of ways: teach constraint simplification
about IfThen/IfElse and teach CSDiags about the case when the cond expr doesn't match
BooleanType. This is rarely necessary, but CSDiags is all about cornercases, and this
does fix a problem in a testcase.
- Be a bit more specific about the constraint failure kind (e.g. say subtype) and when
we have a protocol conformance failure, emit a specific diagnostic about it, instead of
just saying that the types aren't convertible.
Swift SVN r30650
conversion failures, making a bunch of diagnostics more specific and useful.
UnavoidableFailures can be very helpful, but they can also be the first constraint
failure that the system happened to come across... which is not always the most
meaningful one. CSDiag's expr processing machinery has a generally better way of
narrowing down which ones make the most sense.
Swift SVN r30647
diagnose problems inside of them instead of punting on them completely.
This leads to substantially better error messages in many cases, fixing:
<rdar://problem/19870975> Incorrect diagnostic for failed member lookups within closures passed as arguments ("(_) -> _")
<rdar://problem/21883806> Bogus "'_' can only appear in a pattern or on the left side of an assignment" is back
<rdar://problem/20712541> QoI: Int/UInt mismatch produces useless error inside a block
and possibly others. We are not yet capitalizing on available type information we do
have about closure exprs, so there are some cases where we produce
"error: type of expression is ambiguous without more context"
when this isn't strictly true, but this is still a huge step forward.
Swift SVN r30547
we can start taking advantage of ambiguously typed subexpressions in CSDiags. We
start by validating the callee function of ApplyExprs, which substantially improves
our abilities to generate precise diagnostics about malformed calls.
This is the minimal introduction of this concept to CSDiags, a lot of refactoring
is yet to come, however, this is enough to resolve:
<rdar://problem/21080030> Bad diagnostic for invalid method call in boolean expression
<rdar://problem/21784170> Incongruous `unexpected trailing closure` error in `init` function which is cast and called without trailing closure.
one of the testcases from:
<rdar://problem/20789423> Unclear diagnostic for multi-statement closure with no return type
and a bunch of other places where we got weird "unexpected trailing closure"
diagnostics that made no sense. As usual, it is two steps forward and one step back,
as this exposed some other weird latent issues like:
<rdar://problem/21900971> QoI: Bogus conversion error in generics case
Swift SVN r30429
return statements, or a return statement with no operand.
Also, fix a special-case diagnostic about converting a return
expression to (1) only apply to converting the actual return
expression, not an arbitrary sub-expression, and (2) use the
actual operand and return types, not the drilled-down types
that caused the failure.
Swift SVN r30420
facilities used by operators etc. This required a bunch of changes to make
the diagnostics changes strictly an improvement:
- Teach the new path about calls to TypeExprs.
- Teach evaluateCloseness some simple things about varargs.
- Make the generic diagnosis logic produce a better error when there is
exactly one match.
Overall, the resultant diagnostics are a step forward: we now produce candidate
set notes more uniformly, and the messages about some existing ones are
more specific. This is just another stepping stone towards progress though.
Swift SVN r30057
- Remove a weird special case for literals from TypeChecker::typeCheckCondition.
- Enhance FailureDiagnosis::getTypeOfIndependentSubExpression to know about situations
where recursive type checks fail (in some nested situation) but still produce a type
for the top level of the expr tree.
- Remove dead code from CSApply now that you can't branch on Builtin.Int1.
The first & second combine to slightly improve one case I've been looking at in
test/expr/expressions.swift.
Swift SVN r29860
- Fix TypeCheckExpr.cpp to be more careful when propagating sugar from an
argument to the result of the function. We don't want to propagate parens,
because they show up in diagnostics later.
- Restructure FailureDiagnosis::diagnoseFailure() to strictly process the tree
in depth first order. Before it would only do this if contextual typing was
unavailable, leading to unpredictable inconsistencies between diagnostics.
- Always perform diagnoseContextualConversionError early, as part of the thing
that calls the visitor, instead of in each visit method. This may change in
the future, but is a simplification for now.
- Make the operator processing code handle the "candidate is an exact match"
case by emitting a diagnostic indicating that the result type of the operator
must not match expectations, instead of emitting the silly things like
"binary operator '&' cannot be applied to two Int operands" which is obviously
false.
These changes lead to minor improvements across the testsuite, and should make the
diagnostics more predictable for more complex real-world ones, but I haven't gone
through the radars yet.
Major missing pieces:
- CallExpr isn't using the same logic that the operators are.
- When you have a near match (only one argument mismatches) we should specifically
complain about that argument, instead of spewing an entire argument list.
- The noescape function attr diagnostic is being emitted twice now.
Swift SVN r29733
them with diagnoseGeneralFailure() which would miss out on the common cases
where the subexpr of the ParenExpr is the issue.
For example, before we would produce:
t.swift:8:8: error: could not find an overload for '&' that accepts the supplied arguments
if !(x & 4.0) {}
~~~^~~~~~
now we produce:
t.swift:8:6: error: binary operator '&' cannot be applied to operands of type 'Int' and 'Double'
if !(x & 4.0) {}
^
t.swift:8:6: note: overloads for '&' exist with these partially matching parameter lists: (Int, Int)
if !(x & 4.0) {}
^
also, remove some special handling for lvalues and inout from overload
diagnostics, which can't matter anymore.
Swift SVN r29661
This makes it clearer that expressions like "foo.myType.init()" are creating new objects, instead of invoking a weird-looking method. The last part of rdar://problem/21375845.
Swift SVN r29375
result in slightly more descriptive diagnostics in some cases. (Specifically,
for diagnostics involving binary operators.)
(rdar://problem/21080030)
Swift SVN r29020
that make vardecls and subscripts immutable. This makes the indirect cases
a lot more specific ("this is a get-only property" instead of "this is
immutable") and allows us to consolidate a bunch of code:
2 files changed, 45 insertions(+), 119 deletions(-)
Swift SVN r28954
which tell you what the problem is, not just that you have one.
- Enhance diagnostics to be more specific about function calls producing
rvalues.
Swift SVN r28939
- <rdar://problem/16306600> QoI: passing a 'let' value as an inout results in an unfriendly diagnostic
- <rdar://problem/16927246> provide a fixit to change "let" to "var" if needing to mutate a variable
We now refer to an inout argument as such, e.g.:
t.swift:7:9: error: cannot pass 'let' value 'a' as inout argument
swap(&a, &b)
^
we also produce a note with a fixit to rewrite let->var in trivial cases where mutation is
being assed for, e.g.:
t.swift:3:3: note: change 'let' to 'var' to make it mutable
let a = 42
^~~
var
The note is produced by both Sema and DI.
Swift SVN r27774
We now produce diagnostics like:
- cannot pass 'let' value 'a' to mutating unary operator '++'
- cannot pass get-only property 'b' to mutating unary operator '++'
- cannot pass immutable value of type 'Int64' to mutating unary operator '++'
Swift SVN r27772
The rule changes are as follows:
* All functions (introduced with the 'func' keyword) have argument
labels for arguments beyond the first, by default. Methods are no
longer special in this regard.
* The presence of a default argument no longer implies an argument
label.
The actual changes to the parser and printer are fairly simple; the
rest of the noise is updating the standard library, overlays, tests,
etc.
With the standard library, this change is intended to be API neutral:
I've added/removed #'s and _'s as appropriate to keep the user
interface the same. If we want to separately consider using argument
labels for more free functions now that the defaults in the language
have shifted, we can tackle that separately.
Fixes rdar://problem/17218256.
Swift SVN r27704
for a member element reference. This improves error recovery and fixes cases where we'd
reject invalid code in unspaced situations (like "(.x)") this fixes rdar://20251513.
Swift SVN r26406