Справочник по Ada (Ada 2022)
8.6 Контекст разрешения перегрузки
Поскольку объявления могут быть перегружены, возможно, что имя, используемое в коде, имеет более одной возможной интерпретации; в большинстве случаев неоднозначность запрещена. Этот подпункт описывает, как возможные интерпретации разрешаются в фактическую интерпретацию.
Некоторые правила языка (Правила разрешения имён) считаются «правилами перегрузки». Если возможная интерпретация нарушает правило перегрузки, она считается нежелательной интерпретацией; предполагается, что какая-то другая возможная интерпретация является фактической интерпретацией. С другой стороны, нарушения правил, не являющихся правилами перегрузки, не влияют на выбор интерпретации; вместо этого они делают конструкцию некорректной. Для корректности обычно требуется ровно одна приемлемая интерпретация конструкции, которая является «полным контекстом», не считая вложенных полных контекстов.
Правила синтаксиса языка и правила видимости, указанные в 8.3, определяют возможные интерпретации. Большинство правил проверки типов (правила, которые требуют конкретного типа или определённого класса типов, например) являются правилами перегрузки. Различные правила соответствия формальных и фактических параметров также являются правилами перегрузки.
Правила разрешения имён
Разрешение перегрузки применяется отдельно к каждому *полному контексту*, не считая вложенных полных контекстов. Каждый из следующих конструктов является *полным контекстом*:
- Элемент контекста context_item.
- Элемент объявления или объявление declarative_item.
- Оператор statement.
- Связывание аргументов псевдонима pragma_argument_association.
- Выражение *выбора* expression оператора case_statement или выражения case_expression.
- Имя переменной name оператора присваивания assignment_statement A, если выражение A содержит одно или более имён *целей* target_name.
(Общее) *толкование* полного контекста выражает его смысл и включает следующую информацию о составляющих полного контекста, не включая составляющие вложенных полных контекстов:
- для каждого элемента полного контекста, к каким синтаксическим категориям он принадлежит и какими правилами синтаксиса;
- для каждого имени, используемого в коде, какое объявление оно обозначает (и, следовательно, какой вид и какая сущность оно обозначает);
- для полного контекста, который является элементом объявления declarative_item, является ли он завершением объявления и (если да), какое объявление он завершает.
*Возможная интерпретация* — это интерпретация, которая подчиняется правилам синтаксиса и правилам видимости. *Приемлемая интерпретация* — это возможная интерпретация, которая подчиняется *правилам перегрузки*, то есть тем правилам, которые задают ожидаемый тип или ожидаемый профиль или определяют, как конструируется или интерпретируется данная конструкция.
Толкование элемента полного контекста определяется из общего толкования полного контекста в целом. Таким образом, например, «истолкован как вызов функции function_call» означает, что толкование конструкции говорит о том, что она принадлежит к синтаксической категории function_call.
Каждое использование имени обозначает объявление, определяемое его интерпретацией. Оно также обозначает вид, объявленный его обозначенным объявлением, за исключением следующих случаев:
- Если имя появляется в области объявления type_declaration и обозначает то же самое type_declaration, то оно обозначает *текущий экземпляр* типа (а не сам тип); текущий экземпляр типа — это объект или значение типа, связанный с выполнением, которое оценивает используемое имя. Аналогично, если имя появляется в области объявления subtype_declaration и обозначает то же самое subtype_declaration, то оно обозначает текущий экземпляр подтипа. Эти правила не применяются, если имя появляется в *марке подтипа* subtype_mark определения типа доступа к объекту access_definition или в подтипе параметра или результата типа доступа к подпрограмме.
В спецификации аспекта aspect_specification для типа или подтипа текущий экземпляр представляет собой значение типа; это не объект. Если не указано иное, номинальный подтип этого значения задаётся самим подтипом (первый подтип в случае type_declaration) до применения любого предиката, указанного непосредственно в типе или подтипе. Если тип или подтип являются ссылками, связанный с этим значением объект является объектом, связанным (см. 6.2) с вычислением используемого имени.
- Если имя появляется в области объявления обобщения generic_declaration (но не в его части формальных параметров обобщения generic_formal_part) и обозначает то же самое объявление обобщения generic_declaration, то оно обозначает *текущий экземпляр* обобщённого блока (а не сам обобщённый блок). См. также 12.3.
Имя, обозначающее вид, также обозначает сущность этого вида.
*Ожидаемый тип* для данного выражения expression, имени name или другой конструкции определяет, согласно *правилам разрешения типов*, приведённым ниже, типы, рассматриваемые для конструкции во время разрешения перегрузки. Правила разрешения типов поддерживают программирование на основе классов, универсальные литералы, операции диспетчеризации и анонимные типы доступа:
- Если ожидаемый тип конструкции — любой тип в классе типов или универсальный или классный тип для класса, то тип конструкции должен быть разрешён до типа в этом классе или до универсального типа, который охватывает класс.
- Если ожидаемый тип конструкции — конкретный тип T, то тип конструкции должен быть разрешён либо до T, либо до:
T'Class; или
универсального типа, который охватывает T; или
когда T — конкретный анонимный тип доступа к объекту (см. 3.10) с назначенным типом D, до типа доступа к объекту, назначенный тип которого — D'Class или охватывается D; или
когда T — именованный общий тип доступа к объекту (см. 3.10) с назначенным типом D, до анонимного типа доступа к объекту, назначенный тип которого охватывает или охватывается D; или
когда T — анонимный тип доступа к подпрограмме (см. 3.10), до типа доступа к подпрограмме, профиль которого соответствует профилю T.
В некоторых контекстах, таких как в объявлении переименования подпрограммы subprogram_renaming_declaration, Правила разрешения имён определяют *ожидаемый профиль* для данного имени name; в таких случаях имя должно быть разрешено до имени вызываемой сущности, профиль которой совместим с ожидаемым профилем.
Правила корректности
Когда конструкция требует, чтобы ожидаемый тип был *единственным* типом в заданном классе, тип конструкции должен быть определим исключительно из контекста, в котором появляется конструкция, исключая саму конструкцию, но используя требование, чтобы она принадлежала данному классу. Кроме того, контекст не должен ожидать какой-либо тип в некотором классе, который содержит типы данного класса; в частности, конструкция не должна быть операндом преобразования типа type_conversion.
Помимо tested_simple_expression для проверки членства, если ожидаемый тип для имени или выражения не совпадает с фактическим типом имени или выражения, фактический тип должен быть приводим к ожидаемому типу (см. 4.6); кроме того, если ожидаемый тип является именованным типом доступа к объекту с назначенным типом D1, а фактический тип — анонимным типом доступа к объекту с назначенным типом D2, то D1 должен охватывать D2, и имя или выражение должны обозначать представление с уровнем доступности, для которого применяется статически более глубокое отношение; в частности, это не должно обозначать параметр доступа ни самостоятельный объект доступа.
Полный контекст должен иметь по крайней мере одну приемлемую интерпретацию; если их ровно одна, то выбирается именно она.
Предпочтение отдается префиксным операторам (и диапазонам) корневых числовых типов root_integer и root_real. В частности, если две приемлемые интерпретации составляющей полного контекста отличаются только тем, что одна относится к префиксным операторам (или диапазону) типа root_integer или root_real, а другая — нет, то интерпретация, использующая префиксный оператор (или диапазон) корневого числового типа, предпочтительнее.
Аналогично, предпочтение отдается операторам равенства типа universal_access (см. 4.5.2). Если две приемлемые интерпретации составляющей полного контекста отличаются только тем, что одна относится к оператору равенства типа universal_access, а другая — нет, то интерпретация, использующая оператор равенства типа universal_access, является предпочтительной.
Для полного контекста, если существует ровно одна общая приемлемая интерпретация, где интерпретация каждой составляющей такая же, как или предпочтительнее (в вышеуказанном смысле), чем в других общих приемлемых интерпретациях, тогда эта общая приемлемая интерпретация выбирается. В противном случае, полный контекст является неопределённым.
Полный контекст, отличный от pragma_argument_association, не должен быть неоднозначным.
Полный контекст, который является pragma_argument_association, может быть неоднозначным (если для данного псевдокода не указано иное), но только если каждая приемлемая интерпретация аргумента псевдокода является именем, которое статически обозначает вызываемый сущности. Такое имя обозначает все объявления, определённые его интерпретациями, и все представления, объявленные этими объявлениями.
ПРИМЕЧАНИЕ Если имя использования имеет только одну приемлемую интерпретацию, то оно обозначает соответствующую сущность. Однако это не означает, что имя использования обязательно законно, так как существуют другие требования, которые не учитываются при разрешении перегрузки; например, тот факт, что выражение является статическим, является ли объект постоянным, правила соответствия режима и подтипов, правила заморозки, порядок разработки и так далее.
Аналогично, подтипы не учитываются при разрешении перегрузки (нарушение ограничения не делает программу незаконной, но вызывает исключение во время выполнения программы).