Ошибки PascalABC.NET

begin
  var i: integer?;
  i := true ? nil : 5;
end.

Пишет что нельзя присвоить value-типу nil, хотя в данном случае подразумевается что результат будет Nullable. Это ошибка?

В C# это тоже не работает:

int? j = true ? null : 5;

Там сообщение об ошибке другое

Тут разрешает НЕ ставить точки с запятой:

type
  t1=class
    
    b1:byte
    
    public
    
    b2:byte
    
  end;

begin end.

А с методами так не проходит:

type
  t1=class
    
    function f1:byte := 0
    
    public
    
    function f2:byte := 0
    
  end;

begin end.

Так и задумано?

К сожалению, да. В конце секции можно не ставить. Это сделано для совместимости с Delphi и Borland Pascal. Там такое компилируется

type
  t1=record
    b1:byte
  end;

Методов внутри там нет, потому для методов мы это уже запретили

15 мая был откачен фикс #796, и с того момента стало ещё хуже. Теперь не только компилятор не работает для var d: t1 := (a + b).f1. Теперь эта строчка ещё и полностью ломает анализатор кода:

image

Точки сворачивания просто не появляются.

Можете, пожалуйста, объяснить ситуацию с этой issue, чтоб я понимал что является ошибкой а что нет?

И, желательно, исправить хотя бы сообщение об ошибке, потому что Встречено '.', а ожидалось ';' полностью сбивает с толку. В такой короткой строчке ещё можно догадаться что не так, но я успел отбить себе лоб об эту невидимую стену, в местах где всё не так элементарно.

Конструкция (a + b).f1 давала конфликты в грамматике. Как-то мы это пропустили.

Конфликты в грамматике - это вот что такое. Это значит, что правильная программа случайно может оказаться неправильной и наоборот. Причем, непредсказуемо. Это - кошмар.

Эта ошибка просуществовала какое-то время. Плохо, что мы её заметили не сразу. Откатили.

По поводу сообщения об ошибке. Оно Вам не нравится, но оно верное. После (a+b) может идти точка с запятой. Точка теперь идти не может. Вот и выдаётся это сообщение об ошибке.

t1(a + b) - это вызов функции - после него точка может идти

То, что Вы хотите всё-таки точку, вас сбивает

Вот так работает - уже прекрасно )))

begin
  var (a, b) := (3, 5);
  (a+b).ToString.Println
end.

Ну так правильно. В заголовке issue так и сказано, надо не только оператор, а ещё и объявление переменной с : <тип этой переменной>. И это главная проблема. Во всех случаях после скобок даёт ставить точку. По крайней мере я не знаю таких. А тут, вдруг.

Но это всё же не повод говорить что вы никогда не исправите. Хотя бы оставьте ту issue, отложив в долгий ящик. Это всё же лучше.

И что с анализатором кода? Он, вроде, на момент создания issue не был сломал и сломался только после отката. То как он себя в этой ситуации ведёт - ну очень не хорошо.

Ну, мы не умеем побеждать конфликты в грамматике и заставлять солнце двигаться в другую сторону. Можно конечно Issue на что угодно, но не поможет.

Хорошо, если вы не будете исправлять - напишите об этой особенности языка в справке или где то ещё. И добавьте своё сообщение об ошибке, которое будет объяснять почему это всюду после скобочек можно использовать точку, а тут нельзя. Такого типа:
Использование "." после оператора, на строчке с объявлением переменной и её типа - запрещено.
Длинно, но вы поймите, отсутствие нормального объяснения не только сбивает с толку в смысле “а что я сделал не так?”, а ещё и в смысле “это ошибка или так и задумано?”. Через пол года, когда я забуду про эту недо-фичу - я снова потрачу много времени на попытки найти что вызвало такое странное поведение, только чтоб в конце понять что это ещё один дубль #796. Очень демотивирует, знаете ли, когда много труда и времени выбрасывается в форточку.

2 лайка
begin
  var d:=new Dictionary<byte,word>;
  d.Add(1,2);
  //var s:sequence of word := d.Values + word(5);//Ошибка: Нет перегруженной подпрограммы с такими типами параметров
  var s:sequence of word := IEnumerable&<word>(d.Values) + word(5);
  s.Println;//Выводит "2 5", как и ожидалось
end.

Почему тут не даёт написать d.Values + word(5), это ошибка?

Есть серия issue. Общее у них то что у как то полученной записи вызывается метод, и компилятор создаёт для этого вызова не правильный IL код. Прослеживается следующая тенденция:

  • #901 - метод возвращает запись;
  • #910 - конструктор возвращает запись;
  • #974 - глобальная/статичная функция возвращает запись;

Я вот не могу вспомнить, есть ещё какой то способ получить запись? Напишите, если знаете, если с этим способом тоже генерируется не правильный IL код - возможно получится исправить ошибку до того как она сломает чью то программу.

@admin, @ibond, можете пожалуйста посмотреть сюда и сказать, является ли внутренняя ошибка при компиляции test.pas ещё 1 проявлением #951?

Там 5 модулей, циклично скреплённых друг с другом, очень не хочется без лишней причины всё это разгребать))).

свойство типа записи, поле типа запись, приведение оbject к типу запись

Инициализация массива массивов в сокращенной форме. Ошибка выполнения: Индекс находился вне границ массива.

begin
  var c: array of array of integer := ((1,2,3),(4,5,6,7),(6,7,8)); //тут ошибка рантайма
  c.Println
end.

А вот пример, который в справке

begin
  var c: array of array of integer := ((1,2,3),(4,5),(6,7,8));
  c.Println;//[1,2,3] [4,5,0] [6,7,8]
end.

вроде бы и работает, но почему второму под-массиву (ну который первый по индексу) дописывается третий элемент - 0?

Да, это правильно. Память подстраивается под первую строку.

Вообще, эту инициализацию я бы запретил - именно из-за неё у нас большие проблемы с различием между

var x := выражение;

и

То есть, синтаксис старой Delphi нас тянет назад
var x: T := выражение;

Так это ошибка или нет, я не понял. А еще можно спросить, у вас написано в справке, что

var a := Arr(Arr(1,3,5),Arr(7,8),Arr(5,6)); // array of array of integer

но при наведении на переменную в рамке пишет: var a: array of T; как это понять, компилятор не выводит тип или справка не соответствует? %D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA

Это не ошибка.

Система Intellisense, выводящая типы при наведении, у нас не такая мощная и не выводит тип T.