Only represent consts in types using ty::Const
#43
Labels
A-generic-exprs
Generic const expressions
A-unification
Unifying constants in the type system
C-design-docs
Category: This is part of our design documentation
K-impl
Document Kind: regarding implementation
K-solution
Document Kind: elaborating a solution
S-active
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.
Impact
This implementation strategy relies on the following issues:
This implementation strategy would fix the following issues:
where
-clauses #36 Anonymous constants in binders #35 Unused generic parameters of anonymous constants #33 Leaking implementation details during unification #30 Merging impls to be exhaustive #26This implementation strategy would help with the following issues, but will not fix them by itself:
This implementation strategy should not negatively impact any other issue.
Design
Looking at the above topics, there are two core issues this proposal intends to fix:
The idea is that when converting a generic constant in the HIR to a
ty::Const
, we directly lower its body toty::ConstKind::Expr
and removety::ConstKind::Unevaluated
. If a constant does not explicitly mention any generic parameter, we continue to not supply it any generics and are able to evaluate it eagerly before creating itsty::Const
.The new representation of
ty::Const
would be:We either never typecheck generic anonymous constants by themselves, which makes #36 trivial, as they don't matter while everything happens in the same query.
Alternatively, we try to typecheck them once the parent item already finished, avoiding query cycles there. In this case we still have to deal with #36 using some other means.
Lowering from HIR to
ty::Const
For the eager conversion we need to implement and maintain a new lowering from
hir::Expr
toty::Const
. While that one should mostly be trivial to add as long as we sufficiently restrict the allowed expressions, this does add additional complexity to the compiler which we wont really be able to remove in the future.It is still unclear how that deals with constants in function signatures:
The return type of
foo
would be lowered in a way which contains inference variables.So we would have to lower constants and then require all inference variables to be resolved.
It is also unclear how exactly that should deal with region inference, when using something like
func(&my_value)
.Evaluating
ty::Const
As we have to evaluate
ty::Const
without them being typechecked, we can't just use the existing CTFE for this. We would therefore have to add some special evaluation code forExpr
, though that could share its implementation with CTFE.Once we interact with an opaque constant or a function, we can just use ordinary CTFE again.
Lowering concrete consts to
ty::Const
This proposal would start by only lowering constants explicitly mentioning a generic
parameter to
ty::Const
while keeping the current setup of typechecking and evaluating themseparately for concrete constants. For consistency reasons - and for generic const expressions -
it would be nice to also lower concrete constants to
ty::Const
.This would be a breaking change as currently arbitrary expressions are allowed in constants.
This is definitely something we could enable via an edition however.
Generic const expressions and bidirectional inference
With this proposal, it is possible for type inference to flow out of generic constants, allowing the following to compile.
This is only possible as long as we typecheck generic constants together with their parent.
Unless we lower all constants in type to
ty::Const
directly this wouldn't work too well:The text was updated successfully, but these errors were encountered: