Skip to content

Should impls with maximal type structure be allowed to be declared final? #5611

Open
@zygoloid

Description

@zygoloid

Summary of issue:

It's possible for an impl to have a type structure that cannot be further refined (depending on your perspective it'd be maximal or minimal under the partial ordering by type structure; I'm going to consider "more refined" to be "greater" so that such type structures are maximal), and this can occur without the impl being unparameterized. This happens if the impl's only parameters are non-type parameters. For example, in the prelude:

class Int(N:! IntLiteral()) {
  adapt MakeInt(N);
}

impl forall [To:! IntLiteral()] IntLiteral() as ImplicitAs(Int(To)) {
  fn Convert[self: Self]() -> Int(To) = "int.convert_checked";
}

Here, the type structure of this impl is IntLiteral() as ImplicitAs(Int(?)). The impl is parameterized, but this type structure is still maximal: at the type structure level, the value for a non-type argument of a type is always a ?. It can still be specialized -- there could be an impl for IntLiteral() as ImplicitAs(Int(32)), for example -- but only in the same file, and any such impl would need to be in a prioritization block with the above impl.

The consequence of this is that it is sound to permit such an impl to be declared as final. And it's useful to do so: this allows

final impl forall [N:! IntLiteral()]
    IntLiteral() as AddWith(Int(N)) where .Result = Int(N);

... to be declared final, allowing us to know that the type of 1 + n (for n: Int(N)) is Int(N) early in type-checking.

We should consider changing the final rules to allow maximal but parameterized impls to be declared final even if the root type or interface is not owned by the current file.

Details:

It's tempting to treat such impls as being effectively final, but we probably shouldn't: final implies that information from the impl can be used earlier in type-checking, so probably should require an explicit opt-in from the author of the impl.

Any other information that you want to share?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    leads questionA question for the leads team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions