Docs menu

E080: You declared an operator between two types your module doesn't own

What compiler error E080 means, and how to fix it.

Example
// In module "geometry":struct Vec2 { x: int, y: int }operator +(a: Vec2, b: Vec2): Vec2 { ... }   // fine -- geometry owns Vec2// In some OTHER, unrelated module:operator +(a: SomeoneElsesType, b: AnotherModulesType): SomeoneElsesType {    ...}// ERROR: this module owns neither SomeoneElsesType nor AnotherModulesType

An operator declaration needs at least one of its operands to be a struct or enum declared in the SAME module (or main file) as the operator itself. Without this rule, a third module could quietly redefine what + (or any other operator) means between two types it has nothing to do with – and whether that redefinition took effect would depend on whether that third module happened to be imported anywhere in the program, and in what order. That’s the kind of thing that works fine while you’re writing the code and then breaks mysteriously six months later when someone adds an unrelated import.

To fix it, do one of:

  • Move the operator declaration into the module that actually declares
Example
one of the two types.
  • If you don’t own either type and still need this behavior, write it as
Example
an ordinary named function instead (`fn add_vecs(a: Vec2, b: Vec2):Vec2`) -- there's no rule against that, only against redefining anOPERATOR on types you don't own.

This check doesn’t apply to a builtin/string operand at all – string isn’t “declared” by any one module the way a struct or enum is, so lib/std/core/strings.tr’s own operator +(a: string, b: string): string and friends are unaffected by this rule.

Run turf --explain E080 in a terminal to read this again.

Last updated: Oct 15, 2026Edit this page on GitHub

Esc

Type to search.