[swift-dev] CSGen/LinkedExprAnalyzer questions

Jacob Bandes-Storch jtbandes at gmail.com
Fri Dec 30 16:07:58 CST 2016


This is a pretty great bug: https://bugs.swift.org/browse/SR-3483

    let x: Double? = 1

    // error: ambiguous reference to member '+'
    let sum = x! + x! + x!

    //  error: value of optional type 'Double?' not unwrapped; did you mean
to use '!' or '?'?
    let sum: Double = x! + x! + x!

I've been poking around and I think the problem might be in
LinkedExprAnalyzer. This class collects type info about elements in a chain
of binary operators to speed up constraint solving. It does so in this case
by grabbing the DeclRefExpr's type:
https://github.com/apple/swift/tree/474096b9cbd6ff7ac998d7cea41d629512e25570#L230-L239

However, since this is an ASTWalker, (I think) it automatically traverses
into the ForceValueExpr without remembering that the type it finds inside
(from the DeclRefExpr) should have one level of optionality removed when
added to the constraint system.

This theory sort of makes sense to me, but it doesn't explain why the
simpler "let sum = x! + x!" typechecks correctly, because that goes through
the same code path.

Am I correct that the LinkedExprAnalyzer probably needs to make sure it
doesn't keep the Optional when adding the type of a ForceValueExpr? Why
wouldn't this also cause problems for a single binop application?

Would it be more appropriate for LinkedExprAnalyzer to be an ASTVisitor
(ExprVisitor) so that instead of just saying "yes, continue traversing
downwards" (by returning {true, expr}), its ForceValueExpr case could
recursively call visit() and then getAnyOptionalObjectType on the result?


Semi-eptly,
Jacob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20161230/a267b1b7/attachment.html>


More information about the swift-dev mailing list