Whoops, should only look through one level of optionality. You get the gist.
~Robert Widmann > On Dec 31, 2016, at 2:31 PM, Robert Widmann <devteam.cod...@gmail.com> wrote: > > I taught LinkedExprAnalyzer about ForceValueExpr > > if (auto FVE = dyn_cast<ForceValueExpr>(expr)) { > > LTI.collectedTypes.insert(CS.getType(FVE)->lookThroughAllAnyOptionalTypes().getPointer()); > return { false, expr }; > } > > This seems to get it - didn’t check whether this regresses things, but this > seems to be the right fix at a high level. > > ~Robert Widmann > > >> On Dec 31, 2016, at 11:22 AM, Mark Lacey via swift-dev <swift-dev@swift.org >> <mailto:swift-dev@swift.org>> wrote: >> >>> >>> On Dec 30, 2016, at 2:07 PM, Jacob Bandes-Storch via swift-dev >>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: >>> >>> This is a pretty great bug: https://bugs.swift.org/browse/SR-3483 >>> <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. >> >> Yeah I think you’re onto something there. Just looking at the output of the >> constraint solver and where bindings are happening in matchTypes(), it looks >> like the constraint optimizer is trying to force the result type of both >> adds to ‘Double?’ rather than ‘Double’, so we only ever try to solve for >> that type. >> >> I haven’t looked at the constraint optimizer code in a while, so I don’t >> have a lot of insight into the best fix, but it’s clearly the problematic >> piece here. >> >> Mark >> >> >>> 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 >>> >>> <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 >>> _______________________________________________ >>> swift-dev mailing list >>> swift-dev@swift.org <mailto:swift-dev@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-dev >>> <https://lists.swift.org/mailman/listinfo/swift-dev> >> >> _______________________________________________ >> swift-dev mailing list >> swift-dev@swift.org <mailto:swift-dev@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-dev >> <https://lists.swift.org/mailman/listinfo/swift-dev>
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev