lower: 소유 값을 스코프 끝에서 자동으로 해제한다
defer 목록을 '스코프가 아직 갚아야 할 것' 목록으로 일반화했다. defer 블록과 소유 값 해제가 같은 목록에 쓰인 순서대로 들어가고, 모든 이탈 경로가 역순으로 갚는다. 해제에는 값 옆에 플래그를 둔다. 값이 저장될 때 세우고 넘겨줄 때 지운다. 값이 아직 여기 있는 경로에서만 해제되는데, 그건 코드의 모양만 봐서는 알 수 없는 것이다. 검사기가 소유권을 넘기는 사용을 이미 표시해두므로 그것을 읽는다. !void 함수의 빈 return 은 성공이다. 줄 값도 없고 오류도 없다는 뜻인데 프론트엔드가 타입 불일치로 거부하고 있었다. 런타임이 할당/해제 횟수를 센다. owndrop 프로그램이 그 둘이 일치함을 실행으로 증명한다 -- 이른 반환, 이미 넘긴 값, 스코프 끝 전부.
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
// EXIT:0
|
||||
// OUTPUT:balanced
|
||||
unit owndrop;
|
||||
import std.io;
|
||||
import std.sys;
|
||||
|
||||
fn take(p: ^i32) -> void { mem.destroy(p); }
|
||||
|
||||
fn scoped() -> !void {
|
||||
let a: ^i32 = try mem.create(1);
|
||||
let b: ^i32 = try mem.create(2);
|
||||
take(b);
|
||||
}
|
||||
|
||||
fn early(flag: bool) -> !void {
|
||||
let p: ^i32 = try mem.create(3);
|
||||
if flag { return; }
|
||||
take(p);
|
||||
}
|
||||
|
||||
fn main() -> i32 {
|
||||
scoped() catch |e| { return 1; };
|
||||
early(true) catch |e| { return 2; };
|
||||
early(false) catch |e| { return 3; };
|
||||
if sys.allocs() == sys.frees() { io.print("balanced\n"); return 0; }
|
||||
io.print("leaked\n");
|
||||
return 4;
|
||||
}
|
||||
Reference in New Issue
Block a user