В C# это тоже не работает:
int? j = true ? null : 5;
В 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. Теперь эта строчка ещё и полностью ломает анализатор кода:

Точки сворачивания просто не появляются.
Можете, пожалуйста, объяснить ситуацию с этой 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. Очень демотивирует, знаете ли, когда много труда и времени выбрасывается в форточку.
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 код. Прослеживается следующая тенденция:
Я вот не могу вспомнить, есть ещё какой то способ получить запись? Напишите, если знаете, если с этим способом тоже генерируется не правильный 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; как это понять, компилятор не выводит тип или справка не соответствует?
Это не ошибка.
Система Intellisense, выводящая типы при наведении, у нас не такая мощная и не выводит тип T.
Ну, в #884 вы тоже сказали что это слишком сложно для вашего анализатор кода, но оказалось просто. Давайте всё же разберёмся перед тем как говорить что вы не сможете это реализовать.
Институт математики, механики и компьютерных наук ЮФУ, 2005–2021