Support for templated impl declarations (#2700)

The strategy that we use for now to support template instantiation is to check the impl declaration as if it were a generic, but to defer all checking of the impl definition until we see a use in which all template parameters have arguments. At that point, we clone the impl definition and type-check the whole thing, with constant values set on the template parameters corresponding to the given arguments.

No caching of template instantiations is performed yet; each time we form a reference to a template instantiation, we instantiate it afresh. We also don't implement the name lookup rule from #949 yet; lookups during template instantiation look only in the actual type and not in the constraint.

Depends on #2699
This commit is contained in:
Richard Smith
2023-03-22 14:19:02 -07:00
committed by GitHub
parent 4ca2e81877
commit e0c90767be
19 changed files with 491 additions and 64 deletions
+12
View File
@@ -33,7 +33,17 @@ void Pattern::Print(llvm::raw_ostream& out) const {
}
case PatternKind::GenericBinding: {
const auto& binding = cast<GenericBinding>(*this);
switch (binding.binding_kind()) {
case GenericBinding::BindingKind::Checked:
break;
case GenericBinding::BindingKind::Template:
out << "template ";
break;
}
out << binding.name() << ":! " << binding.type();
if (auto value = binding.constant_value()) {
out << " = " << **value;
}
break;
}
case PatternKind::TuplePattern: {
@@ -177,6 +187,8 @@ GenericBinding::GenericBinding(CloneContext& context,
: Pattern(context, other),
name_(other.name_),
type_(context.Clone(other.type_)),
binding_kind_(other.binding_kind_),
template_value_(context.Clone(other.template_value_)),
symbolic_identity_(context.Clone(other.symbolic_identity_)),
impl_binding_(context.Clone(other.impl_binding_)),
original_(context.Remap(other.original_)),