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

Reply via email to