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

[SR-5870] Crash when capture list references parameter of outer single-expression closure #48440

Closed
hamishknight opened this issue Sep 11, 2017 · 6 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software type checker Area → compiler: Semantic analysis

Comments

@hamishknight
Copy link
Collaborator

Previous ID SR-5870
Radar rdar://problem/34394674
Original Reporter @hamishknight
Type Bug
Status Resolved
Resolution Duplicate
Environment

Apple Swift version 4.0 (swiftlang-900.0.63.10 clang-900.0.36)

Target: x86_64-apple-macosx10.9

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, CompilerCrash, TypeChecker
Assignee @xedin
Priority Medium

md5: 21f4fd19bde47e7a35fb7f40b04eec6c

duplicates:

  • SR-3186 Crash when capture list references parameter of outer single-expression closure

is duplicated by:

  • SR-7144 Segmentation fault under swift::ValueDecl::getFormalAccessScope when using a capture list
  • SR-7621 Compiler segfault when capturing weak object
  • SR-8007 SIL crash on capture list

Issue Description:

The following crashes the compiler:

class C {}

func foo(_ callback: (C) -> Void) { callback(C()) }
func bar(_ function: () -> Void) { function() }

foo { c in
    bar { [c] in
        print(c)
    }
}

Attempting to capture c as weak or unowned doesn't crash the compiler, but it does incorrectly yield error message(s):

foo { c in
    // error: 'weak' variable should have optional type '<<error type>>?'
    // error: 'weak' may only be applied to class and class-bound protocol types, not '<<error type>>'
    bar { [weak c] in
        print(c)
    }
}
foo { c in
    // error: 'unowned' may only be applied to class and class-bound protocol types, not '<<error type>>'
    bar { [unowned c] in
        print(c)
    }
}

In both cases, manually binding to a new variable before capturing compiles and runs as expected:

foo { c in
    unowned let c = c
    bar { 
        print(c)
    }
}
@belkadan
Copy link
Contributor

   Assertion failed: (hasInterfaceType() && "No interface type was set"), function getInterfaceType, file /Volumes/Data/swift-public/swift/lib/AST/Decl.cpp, line 1784.

2.  While verifying VarDecl 'c' at <stdin>:6:7

@xedin, any ideas?

@xedin
Copy link
Member

xedin commented Sep 12, 2017

@belkadan Thanks, I will take a look, I think it's related to how we set interface types for parameters in closures, which are allowed to have no types...

@xedin
Copy link
Member

xedin commented Sep 12, 2017

@swift-ci create

@slavapestov
Copy link
Member

The problem is that we type check capture lists before constraint solving, which is usually OK because they can only reference bindings in other statements and outer scopes. It's a problem in single-expression closures because we might not have assigned a type yet.

See TypeCheckConstraints.cpp,

      // For capture lists, we typecheck the decls they contain.
      if (auto captureList = dyn_cast<CaptureListExpr>(expr)) {
        // Validate the capture list.
        for (auto capture : captureList->getCaptureList()) {
          TC.typeCheckDecl(capture.Init, true);
          TC.typeCheckDecl(capture.Init, false);
          TC.typeCheckDecl(capture.Var, true);
          TC.typeCheckDecl(capture.Var, false);
        }
        return finish(true, expr);
      }

For correct behavior, we would type check the Init expression as part of solving the outer constraint system.

@xedin
Copy link
Member

xedin commented Mar 9, 2018

I mentioned that in the radar instead of JIRA 🙁

@slavapestov
Copy link
Member

I looked at this further and it's pretty involved.

  • Pre-check needs to walk into capture list initializer expressions when walking the outer expression.
  • Constraint generation similarly needs to walk into capture list initializers, and set the type of the pattern and capture VarDecl to the result of generating constraints for the initializer.
  • CSApply similarly needs to walk initializers.

In principle this is no different than how single-expression closures work, it just needs to be plumbed through in a few places.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added the crash Bug: A crash, i.e., an abnormal termination of software label Dec 12, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

5 participants