Add interface modifiers (#7625)

This adds most support for default and final methods. Missing components
include rejecting definitions for non-default/final methods, and
permitting out-of-line definitions.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
Christopher Di Bella
2026-08-17 20:49:23 +00:00
committed by GitHub
co-authored by Richard Smith
parent 1e6d554cb6
commit 0f06fe65fa
14 changed files with 1990 additions and 680 deletions
+16 -8
View File
@@ -95,14 +95,10 @@ static auto DiagnoseModifiers(Context& context,
is_definition);
CheckMethodModifiersOnFunction(context, introducer, parent_scope_inst_id,
parent_scope_inst);
RequireDefaultFinalOnlyInInterfaces(context, introducer, parent_scope_id);
if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Interface)) {
// TODO: Once we are saving the modifiers for a function, add check that
// the function may only be defined if it is marked `default` or `final`.
context.TODO(introducer.modifier_node_id(ModifierOrder::Decl),
"interface modifier");
}
RequireDefaultFinalOnlyInInterfaces(context, introducer, parent_scope_id,
is_definition);
// TODO: add check that functions in interfaces may only be defined if they
// are marked `default` or `final`.
if (!self_param_id.has_value() &&
introducer.modifier_set.HasAnyOf(KeywordModifierSet::Method)) {
@@ -135,6 +131,16 @@ static auto GetEvaluationMode(const KeywordModifierSet& modifier_set)
.Default(SemIR::Function::EvaluationMode::None);
}
// Returns the implementation modifier as an enum.
static auto GetInterfaceModifier(const KeywordModifierSet& modifier_set)
-> SemIR::Function::InterfaceModifier {
using enum SemIR::Function::InterfaceModifier;
return modifier_set.ToEnum<SemIR::Function::InterfaceModifier>()
.Case(KeywordModifierSet::Default, Default)
.Case(KeywordModifierSet::Final, Final)
.Default(None);
}
// Tries to merge new_function into prev_function_id. Since new_function won't
// have a definition even if one is upcoming, set is_definition to indicate the
// planned result.
@@ -545,6 +551,7 @@ static auto BuildFunctionDecl(Context& context,
bool is_extern = introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extern);
auto virtual_modifier = GetVirtualModifier(introducer.modifier_set);
auto evaluation_mode = GetEvaluationMode(introducer.modifier_set);
auto interface_modifier = GetInterfaceModifier(introducer.modifier_set);
// Add the function declaration.
SemIR::FunctionDecl function_decl = {SemIR::TypeId::None,
@@ -565,6 +572,7 @@ static auto BuildFunctionDecl(Context& context,
.return_pattern_id = return_pattern_id,
.virtual_modifier = virtual_modifier,
.evaluation_mode = evaluation_mode,
.interface_modifier = interface_modifier,
.self_param_id = self_param_id}};
if (is_definition) {
function_info.definition_id = decl_id;