Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SE-0253] Introduce callables. #24299

Merged
merged 12 commits into from
Aug 27, 2019
Merged

[SE-0253] Introduce callables. #24299

merged 12 commits into from
Aug 27, 2019

Conversation

dan-zheng
Copy link
Contributor

@dan-zheng dan-zheng commented Apr 26, 2019

Implementation for SE-0253.

Introduce callables: values that can be called like functions.
Methods named func callFunction act as call-syntax delegate methods.

struct Adder {
  var base: Int
  func callAsFunction(_ x: Int) -> Int {
    return x + base
  }
}
var adder = Adder(base: 3)
adder(10) // desugars to `adder.callAsFunction(10)`

@dan-zheng dan-zheng added the swift evolution pending discussion Flag → feature: A feature that has a Swift evolution proposal currently in review label Apr 26, 2019
@dan-zheng dan-zheng mentioned this pull request Apr 26, 2019
@@ -5812,6 +5812,9 @@ class FuncDecl : public AbstractFunctionDecl {
bool isConsuming() const {
return getSelfAccessKind() == SelfAccessKind::__Consuming;
}
bool isCallable() const {
return getName().str() == "call" && isInstanceMember();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding an IsCallable bit to FuncDecl?

@lattner's response:

I'd recommend not doing that, unless this is a particularly hot predicate. Cached bits like this have to be kept in sync with the ast. Also, instead of serializing it, if the bit needs to be stored, it can always be computed in the module reader.

// FIXME(TF-444): This logic for `mutating` method calls incorrectly rejects
// IUOs. Performing this ad-hoc check using `originalFn` feels hacky;
// rewrite if possible.
if (!cs.getType(originalFn)->hasLValueType() && selfParam->isInOut()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo: find a better way to handle/diagnose mutating func call methods.
Then, re-enable mutating func call + IUO test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constraint system experts: do you have advice on supporting mutating func callFunction methods more robustly? Perhaps appropriate constraints can be generated in CSSimplify.cpp?

Currently, function expressions in ApplyExpr are always coerced to rvalues, which is problematic for mutating func callFunction method calls. The current workaround in CSApply.cpp is ad-hoc and breaks for mutating func callFunction + IUO.

Here's a small reproducer, with -debug-constraint-solver output:

struct Mutating {
  var x: Int
  mutating func callFunction() {
    x += 1
  }
}
func testIUO(f: inout Mutating!) {
  f() // not okay
  f.callFunction() // okay
}
mutating_iuo.swift:8:3: error: cannot use mutating member on immutable value: 'f' is immutable
  f() // not okay
  ^

cc @xedin

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constraint structure of ApplicableFunction should be good enough here, so it's probably just a problem in the solver. Try doing something like this in simplifyApplicableFnConstraint (where the existing similar call to getFixedTypeRecursive is):

  Type lvType2 = getFixedTypeRecursive(type2, flags, /*wantRValue=*/false);
  type2 = lvType2->hasLValueType() ? getFixedTypeRecursive(lvType2->getRValueType(), flags, /*wantRValue=*/true) : lvType2;

Then you can use lvType2 as the base type when building your constraints for the call to callAsFunction.

Copy link
Contributor Author

@dan-zheng dan-zheng May 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the advice!

I found the blocker for mutating func callAsFunction + IUO. It's the following line in ExprRewriter::finishApply in CSApply.cpp:

fn = cs.coerceToRValue(fn);

ConstraintSystem::coerceToRValue calls TypeChecker::coerceToRValue, which calls cs.setType on expressions and inserts an implicit load expression. Thus, simply caching auto *originalFn = fn before the call to cs.coerceToRValue(fn) is not effective.

If I comment the line fn = cs.coerceToRValue(fn), then the mutating func callAsFunction + IUO example passes, but other lit tests fail.

Any advice/suggestions? If there's some way to clone fn or "undo" the effects of cs.coerceToRValue(fn), that should do the trick. I tried creating an ASTWalker to undo the effects of cs.coerceToRValue(fn), but I'm not sure how to nicely undo ConstraintSystem::setType which expects a non-nullptr Type argument.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you look at the function expression and/or recorded overload choices for the call and make the decision about callable vs. dynamicCallable vs. function before doing any processing?

Copy link
Contributor Author

@dan-zheng dan-zheng Jun 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you look at the function expression and/or recorded overload choices for the call and make the decision about callable vs. dynamicCallable vs. function before doing any processing?

Yes! I believe that's possible and may circumvent the issue. Experimenting now.

Edit: checking "function vs callAsFunction vs @dynamicCallable" may incur a performance impact for resolving all ApplyExprs in ExprRewriter::finishApply. To be benchmarked.

auto &ctx = getASTContext();
// Get all call methods of the nominal type.
// TODO: Consider caching?
SmallVector<FuncDecl *, 4> callMethods;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo: consider caching the func call methods for types?

Such caching of methods is done for @dynamicCallable. There's also a cache for @dynamicMemberLookup types, but it doesn't store methods.

@dan-zheng
Copy link
Contributor Author

Verifying that current tests pass.
@swift-ci Please smoke test

@lattner
Copy link
Contributor

lattner commented Apr 26, 2019

I love how simple and clean this patch is! Maybe you should mention how simple the implementation is in the proposal?

@beccadax
Copy link
Contributor

beccadax commented May 5, 2019

@swift-ci please test compiler performance

@swift-ci
Copy link
Contributor

swift-ci commented May 6, 2019

Summary for master full

Unexpected test results, excluded stats for Deferred, Tagged, Wordy, ProcedureKit

No regressions above thresholds

Debug-batch

debug-batch brief

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (3)
name old new delta delta_pct
Frontend.NumInstructionsExecuted 30,551,710,051,443 30,510,241,830,536 -41,468,220,907 -0.14%
LLVM.NumLLVMBytesOutput 1,168,097,996 1,168,099,088 1,092 0.0%
time.swift-driver.wall 2828.7s 2831.5s 2.8s 0.1%

debug-batch detailed

Regressed (0)
name old new delta delta_pct
Improved (2)
name old new delta delta_pct
Driver.NumDriverPipePolls 205,146 200,092 -5,054 -2.46% ✅
Driver.NumDriverPipeReads 228,691 223,529 -5,162 -2.26% ✅
Unchanged (delta < 1.0% or delta < 100.0ms) (104)
name old new delta delta_pct
AST.NumASTBytesAllocated 72,492,528,282 72,112,510,005 -380,018,277 -0.52%
AST.NumDecls 94,750 94,750 0 0.0%
AST.NumDependencies 213,721 213,731 10 0.0%
AST.NumImportedExternalDefinitions 1,213,161 1,213,161 0 0.0%
AST.NumInfixOperators 35,705 35,705 0 0.0%
AST.NumLinkLibraries 0 0 0 0.0%
AST.NumLoadedModules 255,366 255,366 0 0.0%
AST.NumLocalTypeDecls 123 123 0 0.0%
AST.NumObjCMethods 15,429 15,429 0 0.0%
AST.NumPostfixOperators 18 18 0 0.0%
AST.NumPrecedenceGroups 17,488 17,488 0 0.0%
AST.NumPrefixOperators 90 90 0 0.0%
AST.NumReferencedDynamicNames 122 122 0 0.0%
AST.NumReferencedMemberNames 4,163,187 4,172,680 9,493 0.23%
AST.NumReferencedTopLevelNames 323,183 323,183 0 0.0%
AST.NumSourceBuffers 406,343 406,343 0 0.0%
AST.NumSourceLines 3,165,267 3,165,267 0 0.0%
AST.NumSourceLinesPerSecond 2,365,811 2,359,397 -6,414 -0.27%
AST.NumTotalClangImportedEntities 4,625,668 4,620,302 -5,366 -0.12%
Driver.ChildrenMaxRSS 112,090,402,816 111,918,645,248 -171,757,568 -0.15%
Driver.DriverDepCascadingDynamic 0 0 0 0.0%
Driver.DriverDepCascadingExternal 0 0 0 0.0%
Driver.DriverDepCascadingMember 0 0 0 0.0%
Driver.DriverDepCascadingNominal 0 0 0 0.0%
Driver.DriverDepCascadingTopLevel 0 0 0 0.0%
Driver.DriverDepDynamic 0 0 0 0.0%
Driver.DriverDepExternal 0 0 0 0.0%
Driver.DriverDepMember 0 0 0 0.0%
Driver.DriverDepNominal 0 0 0 0.0%
Driver.DriverDepTopLevel 0 0 0 0.0%
Driver.NumDriverJobsRun 19,330 19,330 0 0.0%
Driver.NumDriverJobsSkipped 0 0 0 0.0%
Driver.NumProcessFailures 0 0 0 0.0%
Frontend.MaxMallocUsage 740,237,692,960 739,718,533,904 -519,159,056 -0.07%
Frontend.NumInstructionsExecuted 30,551,710,051,443 30,510,241,830,536 -41,468,220,907 -0.14%
Frontend.NumProcessFailures 0 0 0 0.0%
IRModule.NumIRAliases 121,579 121,579 0 0.0%
IRModule.NumIRBasicBlocks 4,518,751 4,518,751 0 0.0%
IRModule.NumIRComdatSymbols 0 0 0 0.0%
IRModule.NumIRFunctions 2,138,236 2,138,236 0 0.0%
IRModule.NumIRGlobals 2,238,521 2,238,521 0 0.0%
IRModule.NumIRIFuncs 0 0 0 0.0%
IRModule.NumIRInsts 61,409,727 61,409,727 0 0.0%
IRModule.NumIRNamedMetaData 93,930 93,930 0 0.0%
IRModule.NumIRValueSymbols 3,907,098 3,907,098 0 0.0%
LLVM.NumLLVMBytesOutput 1,168,097,996 1,168,099,088 1,092 0.0%
Parse.NumFunctionsParsed 174,293 174,293 0 0.0%
Parse.NumIterableDeclContextParsed 1,188,598 1,188,598 0 0.0%
SILModule.NumSILGenDefaultWitnessTables 0 0 0 0.0%
SILModule.NumSILGenFunctions 1,101,363 1,101,363 0 0.0%
SILModule.NumSILGenGlobalVariables 41,604 41,604 0 0.0%
SILModule.NumSILGenVtables 12,415 12,415 0 0.0%
SILModule.NumSILGenWitnessTables 46,811 46,811 0 0.0%
SILModule.NumSILOptDefaultWitnessTables 0 0 0 0.0%
SILModule.NumSILOptFunctions 1,566,803 1,566,803 0 0.0%
SILModule.NumSILOptGlobalVariables 42,499 42,499 0 0.0%
SILModule.NumSILOptVtables 20,589 20,589 0 0.0%
SILModule.NumSILOptWitnessTables 102,467 102,467 0 0.0%
Sema.AccessLevelRequest 2,849,865 2,848,107 -1,758 -0.06%
Sema.AttachedPropertyDelegateRequest 1,447,673 1,447,673 0 0.0%
Sema.AttachedPropertyDelegateTypeRequest 252,582 252,582 0 0.0%
Sema.CustomAttrNominalRequest 0 0 0 0.0%
Sema.DefaultAndMaxAccessLevelRequest 63,687 63,682 -5 -0.01%
Sema.DefaultTypeRequest 383,514 383,514 0 0.0%
Sema.EnumRawTypeRequest 18,268 18,268 0 0.0%
Sema.ExtendedNominalRequest 4,100,063 4,095,333 -4,730 -0.12%
Sema.InheritedDeclsReferencedRequest 4,595,397 4,584,590 -10,807 -0.24%
Sema.InheritedTypeRequest 648,443 648,439 -4 -0.0%
Sema.IsDynamicRequest 2,220,945 2,220,945 0 0.0%
Sema.IsFinalRequest 4,012,815 4,002,006 -10,809 -0.27%
Sema.IsObjCRequest 1,948,240 1,947,643 -597 -0.03%
Sema.MangleLocalTypeDeclRequest 246 246 0 0.0%
Sema.NamedLazyMemberLoadFailureCount 23,469 23,444 -25 -0.11%
Sema.NamedLazyMemberLoadSuccessCount 20,548,673 20,592,684 44,011 0.21%
Sema.NominalTypeLookupDirectCount 34,399,299 34,392,017 -7,282 -0.02%
Sema.NumConformancesDeserialized 6,881,324 6,857,504 -23,820 -0.35%
Sema.NumConstraintScopes 19,781,530 19,778,986 -2,544 -0.01%
Sema.NumConstraintsConsideredForEdgeContraction 52,028,407 52,027,835 -572 -0.0%
Sema.NumDeclsDeserialized 52,008,856 51,850,591 -158,265 -0.3%
Sema.NumDeclsFinalized 2,012,925 2,012,925 0 0.0%
Sema.NumDeclsTypechecked 1,040,157 1,040,157 0 0.0%
Sema.NumDeclsValidated 2,440,338 2,440,338 0 0.0%
Sema.NumFunctionsTypechecked 1,081,363 1,081,363 0 0.0%
Sema.NumGenericSignatureBuilders 1,300,109 1,298,403 -1,706 -0.13%
Sema.NumLazyGenericEnvironments 10,513,289 10,490,455 -22,834 -0.22%
Sema.NumLazyGenericEnvironmentsLoaded 224,264 224,280 16 0.01%
Sema.NumLazyIterableDeclContexts 7,308,439 7,301,902 -6,537 -0.09%
Sema.NumLeafScopes 13,108,901 13,106,674 -2,227 -0.02%
Sema.NumTypesDeserialized 17,701,336 17,674,344 -26,992 -0.15%
Sema.NumTypesValidated 1,827,336 1,827,337 1 0.0%
Sema.NumUnloadedLazyIterableDeclContexts 4,819,456 4,822,160 2,704 0.06%
Sema.OverriddenDeclsRequest 8,099,755 8,041,774 -57,981 -0.72%
Sema.PropertyDelegateBackingPropertyInfoRequest 250,065 250,065 0 0.0%
Sema.PropertyDelegateBackingPropertyTypeRequest 252,582 252,582 0 0.0%
Sema.PropertyDelegateTypeInfoRequest 0 0 0 0.0%
Sema.RequirementRequest 71,175 71,175 0 0.0%
Sema.SelfBoundsFromWhereClauseRequest 6,646,075 6,631,056 -15,019 -0.23%
Sema.SetterAccessLevelRequest 159,441 159,441 0 0.0%
Sema.StructuralTypeRequest 0 0 0 0.0%
Sema.SuperclassDeclRequest 88,697 88,718 21 0.02%
Sema.SuperclassTypeRequest 38,570 38,570 0 0.0%
Sema.TypeDeclsFromWhereClauseRequest 33,152 33,147 -5 -0.02%
Sema.USRGenerationRequest 12,963,752 12,845,132 -118,620 -0.92%
Sema.UnderlyingTypeDeclsReferencedRequest 180,187 180,020 -167 -0.09%

Release

release brief

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (3)
name old new delta delta_pct
Frontend.NumInstructionsExecuted 31,105,759,885,984 31,107,308,874,377 1,548,988,393 0.0%
LLVM.NumLLVMBytesOutput 994,400,326 994,402,266 1,940 0.0%
time.swift-driver.wall 5412.1s 5423.0s 10.9s 0.2%

release detailed

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (22)
name old new delta delta_pct
AST.NumImportedExternalDefinitions 233,224 233,224 0 0.0%
AST.NumLoadedModules 16,875 16,875 0 0.0%
AST.NumTotalClangImportedEntities 803,549 803,549 0 0.0%
IRModule.NumIRBasicBlocks 3,956,642 3,956,642 0 0.0%
IRModule.NumIRFunctions 1,793,281 1,793,281 0 0.0%
IRModule.NumIRGlobals 1,971,426 1,971,426 0 0.0%
IRModule.NumIRInsts 36,349,555 36,349,555 0 0.0%
IRModule.NumIRValueSymbols 3,496,248 3,496,248 0 0.0%
LLVM.NumLLVMBytesOutput 994,400,326 994,402,266 1,940 0.0%
SILModule.NumSILGenFunctions 762,829 762,829 0 0.0%
SILModule.NumSILOptFunctions 1,020,342 1,020,342 0 0.0%
Sema.NumConformancesDeserialized 2,358,078 2,358,078 0 0.0%
Sema.NumConstraintScopes 17,910,773 17,910,773 0 0.0%
Sema.NumDeclsDeserialized 6,345,954 6,346,150 196 0.0%
Sema.NumDeclsValidated 1,244,628 1,244,628 0 0.0%
Sema.NumFunctionsTypechecked 489,664 489,664 0 0.0%
Sema.NumGenericSignatureBuilders 211,537 211,537 0 0.0%
Sema.NumLazyGenericEnvironments 1,301,804 1,301,876 72 0.01%
Sema.NumLazyGenericEnvironmentsLoaded 22,517 22,517 0 0.0%
Sema.NumLazyIterableDeclContexts 809,618 809,618 0 0.0%
Sema.NumTypesDeserialized 3,363,826 3,363,865 39 0.0%
Sema.NumTypesValidated 751,167 751,167 0 0.0%

Introduce callables: values that can be called like functions.
Methods named `func callFunction` act as call-syntax delegate methods.

```
struct Adder {
  var base: Int
  func callFunction(_ x: Int) -> Int {
    return x + base
  }
}
var adder = Adder(base: 3)
adder(10) // desugars to `adder.callFunction(10)`
```
@dan-zheng
Copy link
Contributor Author

dan-zheng commented May 17, 2019

Updated based on SE-0253 review feedback.
The call-syntax delegate method name is now callFunction instead of call.
Add trailing closure tests.

Use `callFunction` instead of `call` as the call-syntax delegate method name.
Add trailing closure tests.
@dan-zheng
Copy link
Contributor Author

@swift-ci Please smoke test

@@ -5958,6 +5958,9 @@ class FuncDecl : public AbstractFunctionDecl {
bool isConsuming() const {
return getSelfAccessKind() == SelfAccessKind::__Consuming;
}
bool isCallFunction() const {
return getName().str() == "callFunction" && isInstanceMember();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo: unify "call function"/"call method" terminology, and use one spelling consistently.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any plans to diagnose static or class callFunction?

Copy link
Contributor Author

@dan-zheng dan-zheng May 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What diagnostic do you have in mind?

Originally, SE-0253 was pitched with a new call declaration kind (e.g. call(_ x: Int) -> Int), which did not support static or class. But in the accepted proposal, call-syntax delegate methods are just funcs, so static/class func callFunction(...) is valid.


I suppose we could add call-site diagnostics though. Example:

struct Oops {
  static func callFunction() {
    print("Hi Chéyo")
  }
}
let oops = Oops()
oops()
diag.swift:7:5: error: cannot call value of non-function type 'Oops'
oops()
~~~~^~

We could add a more informative note (e.g. did you mean to call the static function 'Oops.callFunction'?).

Diagnostics can always be added incrementally. 🙂

A detail is that the current diagnostics are being ported from the old system (CSDiag.cpp) to the new request-based system, so adding diagnostics to the old system might be throwaway work. Porting the "function call" diagnostics to the request-based system as a first step might be more productive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Precisely. Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A detail is that the current diagnostics are being ported from the old system (CSDiag.cpp) to the new request-based system, so adding diagnostics to the old system might be throwaway work.

You can actually add diagnostics to a new diagnostic framework right now, it's live, in fact me and couple of others have ported a lot of diagnostics already, see #26074 for the most recent example of how easy it is to add new diagnostics now.

@dan-zheng dan-zheng added swift evolution approved Flag → feature: A feature that was approved through the Swift evolution process and removed swift evolution pending discussion Flag → feature: A feature that has a Swift evolution proposal currently in review labels May 18, 2019
Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the discussion in the review announcement thread, please rename the key function here callAsFunction.

Use `callAsFunction` as the call-syntax delegate method name.
@dan-zheng
Copy link
Contributor Author

dan-zheng commented May 23, 2019

Per the discussion in the review announcement thread, please rename the key function here callAsFunction.

Done in 518bda2.

Some notes, in order of importance:

  • mutating func callAsFunction doesn't work with IUO. See this comment for more details. I couldn't think of better solutions and need help from constraint system experts.

  • Diagnostics for sugared call-syntax calls have room for improvement. This can be done later. Example of current diagnostics:

    struct SimpleCallable {
      func callAsFunction(_ x: Float) -> Float {
        return x
      }
    }
    
    let foo = SimpleCallable()
    
    _ = foo.callAsFunction(1, 1)
    // error: extra argument in call
    // _ = foo.callAsFunction(1, 1)
    //                           ^
    
    _ = foo(1, 1)
    // error: cannot call value of non-function type 'SimpleCallable'
    // _ = foo(1, 1)
    //     ~~~^
    // error: cannot invoke 'foo' with an argument list of type '(Int, Int)'
    // _ = foo(1, 1)
    //     ^
  • Should func callAsFunction methods be cached for nominal types? I haven't done so yet (grep Note: consider caching for places that benefit from caching), but I imagine it would help type-checker performance for code that heavily uses call-syntax sugar.

@dan-zheng dan-zheng requested a review from rjmccall May 23, 2019 18:15
include/swift/AST/Decl.h Outdated Show resolved Hide resolved
include/swift/AST/Decl.h Show resolved Hide resolved
lib/Sema/CSApply.cpp Show resolved Hide resolved
lib/Sema/CSSimplify.cpp Outdated Show resolved Hide resolved
@rjmccall
Copy link
Contributor

Thanks. I haven't given the constraint logic a good once-over; do you want to get mutating calls working first?

@dan-zheng
Copy link
Contributor Author

dan-zheng commented May 30, 2019

Thanks. I haven't given the constraint logic a good once-over; do you want to get mutating calls working first?

Sure thing. I missed your earlier suggestion regarding mutating calls, I'll explore that and get back to you. To be clear, mutating calls currently work, but mutating + IUO calls do not.

@rxwei
Copy link
Contributor

rxwei commented Jun 27, 2019

Would it be acceptable merge this partial implementation as is and start separate PRs later to support mutating and IUO?

@@ -106,8 +106,12 @@ struct Mutating {
}
}
func testMutating(_ x: Mutating, _ y: inout Mutating) {
_ = x() // expected-error {{cannot use mutating member on immutable value: 'x' is a 'let' constant}}
_ = x.callAsFunction() // expected-error {{cannot use mutating member on immutable value: 'x' is a 'let' constant}}
// TODO: Improve this error to match the error using a direct `callAsFunction` member reference.
Copy link
Contributor Author

@dan-zheng dan-zheng Aug 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this diagnostic regressed - the diagnostic is now produced from failed member constraint instead of custom CSApply diagnostic hack. cc @xedin regarding ideas for improving/fixing this.

The diagnostic below in testInout has improved however - it is now in parity with direct callAsFunction calls.

@dan-zheng
Copy link
Contributor Author

dan-zheng commented Aug 11, 2019

I believe the main constraint system changes requested by @xedin are done, so this patch is ready for re-review. Some func callAsFunction diagnostics are suboptimal though - details in comments above.

@dan-zheng
Copy link
Contributor Author

Verifying that tests pass.
@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 4cb7ebf

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 4cb7ebf

lib/Sema/CSSimplify.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks much better now, thank you! Still needs a final push though.

@dan-zheng
Copy link
Contributor Author

dan-zheng commented Aug 12, 2019

There's one failing test (expr/delayed-ident/static_var.swift) as of the recent constraint system changes in 8dcd1c6:

Assertion failed: (unwrappedType && "Unwrapped type must not be null"), function ForceOptional, file /Users/danielzheng/swift-master/swift/lib/Sema/CSFix.h, line 272.
Stack dump:
0.	Program arguments: /Users/danielzheng/swift-master/build/Ninja-ReleaseAssert+stdlib-Release/swift-macosx-x86_64/bin/swiftc -frontend -target x86_64-apple-macosx10.9 -module-cache-path /Users/danielzheng/swift-master/build/Ninja-ReleaseAssert+stdlib-Release/swift-macosx-x86_64/swift-test-results/x86_64-apple-macosx10.9/clang-module-cache -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -swift-version 4 -typo-correction-limit 10 -typecheck -verify -disable-objc-attr-requires-foundation-module /Users/danielzheng/swift-master/swift/test/expr/delayed-ident/static_var.swift
1.	Swift version 5.1-dev (LLVM 200186e28b, Swift 4cb7ebf8a0)
2.	While type-checking statement at [/Users/danielzheng/swift-master/swift/test/expr/delayed-ident/static_var.swift:49:1 - line:49:34] RangeText="var _: HasClosure = .factoryOpt(3"
3.	While type-checking declaration 0x7fc815817b18 (at /Users/danielzheng/swift-master/swift/test/expr/delayed-ident/static_var.swift:49:1)
4.	While type-checking expression at [/Users/danielzheng/swift-master/swift/test/expr/delayed-ident/static_var.swift:49:21 - line:49:34] RangeText=".factoryOpt(3"
0  swiftc                   0x000000010d58f215 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 37
1  swiftc                   0x000000010d58e258 llvm::sys::RunSignalHandlers() + 248
2  swiftc                   0x000000010d58f808 SignalHandler(int) + 264
3  libsystem_platform.dylib 0x00007fff6aeeeb5d _sigtramp + 29
4  swiftc                   0x000000010f96c2c3 cmark_strbuf__initbuf + 128062
5  libsystem_c.dylib        0x00007fff6ada86a6 abort + 127
6  libsystem_c.dylib        0x00007fff6ad7120d basename_r + 0
7  swiftc                   0x000000010d89c003 swift::constraints::ForceOptional::create(swift::constraints::ConstraintSystem&, swift::Type, swift::Type, swift::constraints::ConstraintLocator*) (.cold.2) + 35
8  swiftc                   0x000000010a2d282c swift::constraints::ForceOptional::create(swift::constraints::ConstraintSystem&, swift::Type, swift::Type, swift::constraints::ConstraintLocator*) + 108
9  swiftc                   0x000000010a2ae96f swift::constraints::ConstraintSystem::simplifyApplicableFnConstraint(swift::Type, swift::Type, swift::OptionSet<swift::constraints::ConstraintSystem::TypeMatchFlags, unsigned int>, swift::constraints::ConstraintLocatorBuilder) + 3007
10 swiftc                   0x000000010a2b2cbc swift::constraints::ConstraintSystem::simplifyConstraint(swift::constraints::Constraint const&) + 1980
11 swiftc                   0x000000010a2bb8c7 swift::constraints::ConstraintSystem::simplify(bool) + 87
12 swiftc                   0x000000010a26121c swift::constraints::TypeVariableBinding::attempt(swift::constraints::ConstraintSystem&) const + 412
13 swiftc                   0x000000010a2cc7a4 swift::constraints::BindingStep<swift::constraints::TypeVarBindingProducer>::take(bool) + 468
14 swiftc                   0x000000010a2bd162 swift::constraints::ConstraintSystem::solve(llvm::SmallVectorImpl<swift::constraints::Solution>&) + 338
15 swiftc                   0x000000010a3144dd swift::constraints::ConstraintSystem::salvage(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::Expr*) + 285
16 swiftc                   0x000000010a2be89c swift::constraints::ConstraintSystem::solve(swift::Expr*&, swift::Type, swift::ExprTypeCheckListener*, llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::FreeTypeVariableBinding) + 508

I'm not exactly sure what is the cause.
@xedin: is it possible that this change is related to the change in definition of origType2?

@xedin
Copy link
Contributor

xedin commented Aug 12, 2019

Maybe, I'm not sure either... Maybe ForceOptional has to get l-value stripped away before giving type to a fix?

- Rename `isValidDynamicallyCallMethod` to `isValidDynamicCallableMethod`.
- Add todo hint regarding `static func callAsFunction`, if it is to be supported.
- Restore `var origType2` before unwrapping optionality.
  - This fixes `expr/delayed-ident/static_var.swift`.
@dan-zheng
Copy link
Contributor Author

I believe all comments have been addressed (besides improving diagnostics).
@swift-ci Please test

@dan-zheng dan-zheng requested a review from xedin August 24, 2019 07:23
@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 4cb7ebf

@dan-zheng
Copy link
Contributor Author

@swift-ci Please test macOS

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you!

@dan-zheng
Copy link
Contributor Author

Add todo comment references to SR-11378, tracking the improvement of func callAsFunction diagnostics.

@dan-zheng
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - cebbd63

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - cebbd63

@dan-zheng
Copy link
Contributor Author

Thank you to all reviewers! Merging now.

@dan-zheng dan-zheng merged commit f44064c into swiftlang:master Aug 27, 2019
@dan-zheng dan-zheng deleted the callables branch August 27, 2019 06:56
dan-zheng added a commit that referenced this pull request Sep 1, 2019
Changelog entry for SE-0253.
Follow-up to implementation: #24299.
ematejska added a commit that referenced this pull request Sep 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
swift evolution approved Flag → feature: A feature that was approved through the Swift evolution process
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants