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

sink in subscripts don't move arguments #1600

Open
seanbaxter opened this issue Oct 6, 2024 · 1 comment
Open

sink in subscripts don't move arguments #1600

seanbaxter opened this issue Oct 6, 2024 · 1 comment

Comments

@seanbaxter
Copy link

public type Foo : Deinitializable {

  public memberwise init
  public var data : Int

  public subscript(_ arg: sink Int): Int {
    inout {
      yield &data
    }
  }
}

public fun f(_ arg: sink Int) { }

public fun main() {
  var obj = Foo(data:1)

  let x = 1;
  let y = 2;

  // This should relocate x.
  inout d = obj[x]
  &d = 50;

  // Can still print x. Why no error?
  print(x);

  // This should relocate y.
  f(y);

  // Error!
  print(y); 
}

I can use x after passing it to a subscript taking a sink parameter.
I cannot use y after passing it to a normal function taking a sink parameter.

@kyouko-taiga
Copy link
Contributor

Minimal reproducer:

subscript p(_ arg: sink Int): Int {
  let { yield arg }
}

public fun use(_ x: Int) { }

public fun main() {
  var x = 42
  let d = p[x]
  use(d)
  use(x)
}

Problem seems to be that the abstract interpreter doesn't properly update the sate of x after the end d's projection. See corresponding the IR:

external fun FunctionDecl(2424834)() -> {} {
b0(%b0#0 : &{}):
  // var x = 42
  %i0.0: &Int = alloc_stack Int
  %i0.1: &word = subfield_view %i0.0, 0
  %i0.2: &word = access [set] %i0.1
  store i64(0x2a), %i0.2
  end_access %i0.2

  // let d = p[x]
  %i0.4: &Int = access [sink] %i0.0
  %i0.5: &Int = project SubscriptImpl(458754), %i0.4
  %i0.6: &Int = access [let] %i0.5

  // use(d)
  %i0.7: &{} = alloc_stack {}
  %i0.9: &{} = access [set] %i0.7
  call @FunctionDecl(851970)(%i0.6) to %i0.9
  end_access %i0.6
  end_project %i0.5      // <- %i0.0 should be considered moved here
  end_access %i0.4
  end_access %i0.9
  mark_state deinitialized %i0.7
  
  // use(x)
  %i0.13: &{} = alloc_stack {}
  %i0.14: &Int = access [let] %i0.0
  %i0.15: &{} = access [set] %i0.13
  call @FunctionDecl(851970)(%i0.14) to %i0.15
  end_access %i0.14
  end_access %i0.15
  mark_state deinitialized %i0.13
  dealloc_stack %i0.13
  dealloc_stack %i0.7
  mark_state deinitialized %i0.0
  dealloc_stack %i0.0
  mark_state initialized %b0#0
  return
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants