Skip to content

Generic const parameter types #28

Open
@lcnr

Description

@lcnr

What is this

This is a design document for const generics. Any discussions about its content should be on zulip. The conclusions of these discussions should then be edited back into this issue. Please do not post any comments directly in this issue.

Content

We want to support the types of const parameters
to depend on other generic parameters.

fn foo<const LEN: usize, const ARR: [u8; LEN]>() -> [u8; LEN] {
    ARR
}

This is currently forbidden during name resolution.

Generic const param types in type dependent paths

Probably the biggest blocker is type-checking const arguments
for generic parameters. This currently uses a hack
to supply the DefId of the corresponding const parameter.

Now, let's look at the following:

fn foo<const N: usize, const M: [u8; N]>() {}

fn bar() {
    foo::<3, { [0; 3] }>();
}

Here the expected type of { [0; 3] } should be [u8; 3]. With the
current approach it is [u8; N] instead. To fix this we would have to
supply the affected queries the expected type of the const argument itself
or use a (DefId, SubstsRef<'tcx>) pair instead.

Doing so isn't trivial because we have to worry about accidentially
ending up with different types for the same const argument which would
break stuff.

Potential dangers include partially resolved types and projections.

Variance for generic parameters used in const param types

The variance of a generic parameter used in the type of a const parameter should probably be influenced as if it was used in the type of a field.

// `T` is covariant because it is used in `DEFAULT`.
struct DefaultProvider<T, const DEFAULT: T>;

// `T` is invariant because it is used in `DEFAULT`.
struct WithItem<T: Iterator, const MAP: <T as Iterator>::Item>;

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-param-typesConst parameter typesC-design-docsCategory: This is part of our design documentationK-behaviorDocument Kind: regarding user visible behaviorK-implDocument Kind: regarding implementationP-necessaryPriority: will be needed at some pointS-blocked

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions