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

Runtime crash when accessing a field that was captured before it was initialized #4301

Open
chalcolith opened this issue Jan 10, 2023 · 2 comments
Labels
bug Something isn't working help wanted Extra attention is needed triggers release Major issue that when fixed, results in an "emergency" release

Comments

@chalcolith
Copy link
Member

chalcolith commented Jan 10, 2023

The following program crashes in the lambda {() => _foo.n }:


class Foo
  let n: USize
  
  new create(n': USize) =>
    n = n'

class Bar
  let _foo: Foo
  let lazy: {(): USize} = {() => _foo.n }
  
  new create() =>
    _foo = Foo(123)

actor Main
  let _env: Env
  let _bar: Bar

  new create(env: Env) =>
    _env = env
    _bar = Bar
    run_me()
  
  be run_me() =>
    _env.out.print("n is " + _bar.lazy().string())

The lambda captured the pointer to _foo before it was initialized (if you initialize _foo directly and not in the constructor everything works fine).

@chalcolith chalcolith added bug Something isn't working needs discussion Needs to be discussed further discuss during sync Should be discussed during an upcoming sync labels Jan 10, 2023
@SeanTAllen SeanTAllen added triggers release Major issue that when fixed, results in an "emergency" release help wanted Extra attention is needed and removed needs discussion Needs to be discussed further labels Jan 10, 2023
@jemc
Copy link
Member

jemc commented Jan 10, 2023

Here's a revised program showing that it still crashes even when the assignment isn't in a field initializer:

class Foo
  let n: USize
  
  new create(n': USize) =>
    n = n'

class Bar
  let _foo: Foo
  let lazy: {(): USize}
  
  new create() =>
    lazy = {() => _foo.n }
    _foo = Foo(123)

actor Main
  let _env: Env
  let _bar: Bar

  new create(env: Env) =>
    _env = env
    _bar = Bar
    _env.out.print("Hello")
    run_me()
  
  be run_me() =>
    _env.out.print("n is " + _bar.lazy().string())

@jemc
Copy link
Member

jemc commented Jan 10, 2023

This program should result in a compile-time error that says you can't access the _foo field on a Bar tag.

The captured Bar must be a tag because it hasn't been fully initialized with all fields yet.

@SeanTAllen SeanTAllen removed the discuss during sync Should be discussed during an upcoming sync label Jan 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed triggers release Major issue that when fixed, results in an "emergency" release
Projects
None yet
Development

No branches or pull requests

3 participants