talk_dev's Journal

Talk of the Town

Today's Typecheck
talk_dev posted a new release

Ownership Gets Its Timing Right

Talk now does a sharper job of moving, borrowing, dropping, and showing those facts at the right moment.


Today's release tightens the route from source ownership to lowered code and editor feedback. The big story is timing: owned locals drop when their scopes end, moved values stay moved, and shared compiler paths stay shared instead of multiplying behind the curtain.

Branch Locals Leave Before the Shared Tail

The lowering tests now insist that owned values made inside if branches are freed before control rejoins the common tail. In the checked IR, both branch-local strings are freed, and the final continuation appears only once.

That means Talk can keep cleanup precise without duplicating the rest of the function for every branch.

func f(a: Bool, b: Bool) -> Int {
	if a {
		// Local s is owned only by this
		// branch
		let s = "a" + "b"
	} else {
		// Local t is the matching owned
		// value from the other branch
		let t = "c" + "d"
	}
	if b {} else {
	}
	// The final value is reached
	// after branch cleanup rejoins
	123
}
f(true, false)
Tail Values Now Pass Through Scope Cleanup

A function that computes a tail value after creating an owned string now lowers through a drop_scope wrapper. The changed test checks that the string is freed before the return continuation receives the final integer.

The visible promise is simple: returning a value does not skip the owned locals waiting at the door.

func f() -> Int {
	// Owned local s needs cleanup at
	// function scope exit
	let s = "a" + "b"
	// The tail value must survive
	// while cleanup runs first
	123
}
// Calling f exercises the lowered
// return path
f()
Drops happen where the story says they should.- The day's release, in one line
Landing in This Release
func f(a: Bool, b: Bool) -> Int {
	if a {
		// The then branch creates owned
		// local s inside a short scope
		let s = "a" + "b"
	} else {
		// The else branch creates owned
		// local t with the same cleanup
		// problem
		let t = "c" + "d"
	}
	// Both branches rejoin before the
	// later if and final result
	if b {} else {
	}
	123
}
f(true, false)
Repeated Empty Ifs Share Their Road Home

Sequential statement-level ifs now share their lowered tail instead of copying it again and again. The changed lowering test counts occurrences of the final continuation and expects only one or two, not a little parade of duplicates.

This is not a new syntax feature, but it is a compiler invariant users can feel in steadier generated IR.

func f(a: Bool, b: Bool, c: Bool, d: Bool) -> Int {
	// The first empty branch should
	// not clone the whole remaining
	// tail
	if a {} else {
	}
	if b {} else {
	}
	if c {} else {
	}
	// Four sequential branches stress
	// the join sharing
	if d {} else {
	}
	// The single final result is the
	// tail being shared
	123
}
f(true, false, true, false)
Borrow Edges Are Narrower and Safer

Type checking now keeps auto-borrowing at the immediate call boundary instead of letting it leak under nested type constructors or contravariant function parameters. Tests reject borrowed returns where owned values are required, while still allowing a mutable borrow return to downgrade to a shared borrow return.

The result is a clearer split: calls may borrow an argument for the call, but nested boxes and function slots must still match their real ownership shape.

// no-core
struct String {
	let length: Int
}
// The function promises a shared
// borrow result
func as_shared(s: &mut String) -> &String {
	// Returning s downgrades the
	// mutable borrow to shared
	s
}
// A function value returning &mut
// String fits a shared-return slot
let f: (&mut String) -> &String = func(s: &mut String) -> &mut String {
	s
}
The Editor Can See the Ownership Ledger

Hover output and LSP inlay hints now read from ownership facts, showing moves, borrows, and drops in the editor. Tests check for labels such as borrow, move, and drop, and for hover text that marks owned values.

Diagnostics also keep going file by file: ownership errors can survive beside unrelated type errors in another document.

permalinkrecent entriesarchive
The Daily Talk - What's New in Talk - Release Notes for June 26, 2026