Method called as a function
ErrorSafe fixlen(), sum() and contains(x) are methods of arrays: xs.len(), not len(xs). Math is the same: sqrt(x), pow(x, 2) and max(a, b) are the methods x.sqrt(), x.pow(2) and a.max(b). The methods of your own classes and enums are the same: when name is a method of the class Actual, name(self) becomes self.name(). When no function of that name exists and the first argument has that method, the error offers the method call. A name that the first argument's type has no method for, such as abs(n) with n: i64, is E0052.
Two more forms have the same error:
- The first argument is an optional, such as
name(a)witha: Actual?, and the type inside it has the method. The error says thatamay beNone. The fix isa?.name(). It is always unsafe, because?.skips the call whenaisNone. When the method gives a value,?.also makes the result optional. - The call is in a method, and no function of that name exists. The class or the enum of the method has a method of that name. The fix is
self.name(args). When the first argument has the method too, the fix uses that argument instead. But when the call has as many arguments as the method ofself, and the first argument fits its first parameter, the fix isself.name(args). Somerge(other)becomesself.merge(other), notother.merge().
The fix is safe when the method call takes the remaining arguments as written. For a method of your own, that means each remaining argument fits its parameter as receiver.method(args) checks it, and the method has no type parameters of its own. Otherwise it is unsafe, and the arguments still need fixing: len(xs, 1) becomes xs.len(1), and len() takes no arguments. It is also unsafe when the rewrite would delete a comment inside the call.
The self fix deletes nothing, so a comment does not make it unsafe. A label or a type argument makes it unsafe, because a method call takes neither (E0055, E0137). The checker finds the type of the first argument before it knows the method, so a literal can make the fix unsafe when the call is correct. An example is scale(2) for fn scale(self, k: f64). Then the fix does not say that the arguments are wrong.
Why
These operations are methods, and Sisu has no built-in functions of the same names. Each belongs to the value it works on, so it is called on that value. You can still define a function of your own that takes an array or a number, even one named len or sqrt, and call it as a function.
Broken
fn main() {
let xs = [1, 2, 3]
print(len(xs))
}
What sisu says
error[E0070]: `len` is a method, not a function --> E0070.sisu:3:11 | 3 | print(len(xs)) | ^^^ | help: call `len` as a method | 3 - print(len(xs)) 3 + print(xs.len()) | sisu: 1 error sisu: for more on a code, run `sisu explain <code>`: E0070
Fixed
fn main() {
let xs = [1, 2, 3]
print(xs.len())
}
Sisu