Skip to content

Как читать ошибки компилятора

This content is not available in your language yet.

Питонист привыкает к ошибкам во время выполнения: запустил, упало, посмотрел трейсбек. В Mojo большинство ошибок вылезает до запуска, и выглядят они непривычно — иногда на пол-экрана. Пугаться не нужно: структура у них жёсткая, и читать их можно быстро.

Приятная особенность Mojo 1.0: компилятор часто пишет прямо в сообщении, как чинить. Не «type mismatch», а «используйте x[len(x) - 1]».

Вот типичная ошибка целиком:

main.mojo:4:15: error: invalid call to '__add__': value passed to 'rhs'
cannot be converted from 'Int' to 'Float64'
print(a + b)
~~~~^
oss/modular/mojo/stdlib/std/builtin/simd.mojo:1034:1: note: function declared here
def __add__(self, rhs: Self) -> Self # note - synthetic signature
^

Разбираем по частям:

ЧастьЧто означает
main.mojo:4:15Файл, строка, колонка. Именно здесь компилятор споткнулся
error:Сама проблема. Читается как обычное предложение
print(a + b)Ваш код — чтобы не переключаться в редактор
~~~~^Подчёркивание: ^ показывает точное место, ~ — участвующее выражение
note:Дополнительный контекст: где объявлено то, что не подошло

Ключевое правило: note — это не отдельные ошибки. Это пояснения к одной ошибке. Одна ошибка может тащить за собой десяток note.

Компилятор часто выдаёт несколько ошибок подряд, но вторая и третья обычно следствия первой. Порядок действий такой:

  1. Найдите первое error: в выводе.
  2. Посмотрите на номер строки и подчёркивание.
  3. Почините.
  4. Соберите снова — и очень часто остальные ошибки исчезнут сами.
oss/modular/mojo/stdlib/std/collections/list.mojo:428:1: note: candidate not viable

Такие пути ведут в исходники стандартной библиотеки Mojo. Их упоминание означает не «сломалась стандартная библиотека», а «вот как объявлено то, что вы пытались вызвать». Ошибка при этом ваша — в строке, указанной первой.

Самое пугающее с виду сообщение. Возникает, когда у функции или конструктора несколько вариантов (перегрузок), и ни один не подошёл:

main.mojo:9:37: error: no matching function in initialization
var measurements = List[Float64](21.5, 23.0, 19.8, 24.2)
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
list.mojo:428:1: note: candidate not viable: unexpected argument
def __init__(out self)
list.mojo:435:1: note: candidate not viable: missing required argument: 'capacity'
def __init__(out self, *, capacity: Int)
list.mojo:450:1: note: candidate not viable: missing required argument: 'length'
def __init__(out self, *, length: Int, fill: T)
...

Читается это так: «я знаю восемь способов создать List, покажу каждый и почему он не подошёл». Дальше вы просматриваете список и ищете тот вариант, который хотели. В примере выше подходящего конструктора «просто перечислить значения» нет вовсе — значит, создавать список надо иначе, литералом:

var measurements: List[Float64] = [21.5, 23.0, 19.8, 24.2]

В Mojo 1.0 многие сообщения содержат прямую инструкцию. Стоит дочитывать до конца, прежде чем лезть в поиск:

note: constraint failed: negative indexing is not supported, use e.g. `x[len(x) - 1]`
Что это значитОтрицательный индекс.
Как исправитьРешение прямо в тексте ошибки.
error: unparenthesized lambda arguments are not supported; write them in parentheses, with types, e.g. `lambda (x: Int, y: Int) -> Int: x + y`
Что это значитЛямбда написана по-питоновски.
Как исправитьГотовый образец правильной формы — в самом сообщении.
error: use of unknown declaration 'Python'; did you mean to import it from 'std.python'? Add 'from std.python import Python'
Что это значитЗабыт импорт.
Как исправитьКомпилятор называет и модуль, и строку, которую нужно дописать.
СообщениеПо-русскиЧто делать
use of unknown declaration 'x'Имя x компилятору неизвестноОпечатка или забытый импорт
'String' value has no attribute 'uppercase'У типа нет такого методаПроверьте название: upper(), а не uppercase()
argument type must be specifiedУ аргумента не указан типДопишите аннотацию
invalid call to 'add': unexpected argumentЛишний аргумент при вызовеСверьтесь с сигнатурой в note ниже
cannot be converted from 'Int' to 'Float64'Нет неявного преобразованияПриведите явно: Float64(x)
cannot call function that may raise in a context that cannot raiseВызов «бросающей» функции из «небросающей»Добавьте raises в сигнатуру или оберните в try
value ... cannot be implicitly copiedТип не разрешает неявное копированиеa^, a.copy() или трейт ImplicitlyCopyable
expressions must not appear at file scopeКод вне функцииПеренесите в def main()
classes are not supported yetclass в языке нетИспользуйте struct
failed to parse the provided Mojo source moduleИтоговая строка после ошибок разбораИгнорируйте, смотрите выше
failed to run the pass managerИтоговая строка после ошибок этапа компиляцииТо же самое

warning: не мешает сборке, но обычно означает, что конструкция скоро перестанет работать:

warning: implicit declaration of 'left' is deprecated;
add 'var' before the assignment target

Такие предупреждения — бесплатная страховка от будущих поломок. Чините их сразу, пока это одна строка, а не сотня.

  1. Упростите пример. Выкиньте всё лишнее, пока не останется 5–10 строк, которые всё ещё не собираются. Часто на этом шаге причина становится очевидной без всякой посторонней помощи.

  2. Проверьте, не устарел ли код. Если вы взяли его из статьи или у нейросети, велика вероятность, что он написан до Mojo 1.0 — см. Устаревшие конструкции.

  3. Спросите. Форум Modular — там отвечают в том числе разработчики языка. Приложите минимальный пример, полный текст ошибки и вывод mojo --version.

🎯 Проверь себя

В выводе десять строк с `note:` и одна с `error:`. Сколько у вас ошибок?

Одна. Строки note — это пояснения к ней: где объявлена функция, какие были варианты и почему они не подошли.

Компилятор указывает на файл `oss/modular/mojo/stdlib/std/collections/list.mojo`. Значит, баг в стандартной библиотеке?

Нет. Так компилятор показывает, как объявлено то, что вы вызывали. Ошибка — в вашем файле, он указан в первой строке сообщения.

Вышло пять ошибок сразу. С какой начинать?

С первой. Остальные часто — её последствия и исчезают сами после исправления.

Разобрались с ошибками — можно спокойно писать код: дальше начинается базовый синтаксис Mojo.

Примеры проверены на Mojo 1.0.0

Тексты курса — CC BY-NC-SA 4.0, код примеров — Apache 2.0