ISTM that the docs imply this:
When the garbage collector finds an unreachable block with an associated finalizer, it clears the association and runs finalizer(obj) in a separate goroutine. This makes obj reachable again, but now without an associated finalizer. Assuming that SetFinalizer is not called again, the next time the garbage collector sees that obj is unreachable, it will free obj.
As long as we assume that the GC only collects unreachable data (which seems extremely plausible), it won't collect data that has a finalizer without running said finalizer.
I do think there are still some subtleties though. For example, if your finalizer does not actually *use* its parameter, the data might be considered unreachable (and collected) before you would consider the finalizer to "have run". e.g. if your finalizer is
func finalize(p *int) {
fmt.Println("finalizer ran")
}
`p` might be collected before `finalizer ran` is printed. That is, your statement is only true if by "finalizer is run" you mean "finalizer is called", not "finalizer has returned".
At least as far as I understand it. Finalizers are subtle and I won't claim to actually understand them.